import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

public class MatrixManipulatorTest
{
    @Test
    public void testAddable()
    {
        int[][] mat1 = {
                { 1, 2, 3, 4, 5 },
                { 6, 7, 8, 9, 10 }
        };
        
        int[][] mat2 = {
                {11, 12, 13, 14, 15},
                {16, 17, 18, 19, 20}
        };
        
        assertTrue(MatrixManipulator.addable(mat1, mat2));
        
        
        mat2 = new int[][] {
                {11, 12, 13, 14, 15, 21},
                {16, 17, 18, 19, 20, 22}
        };
        
        assertTrue( ! MatrixManipulator.addable(mat1, mat2) );
        
        
        mat2 = new int[][] {
            {11, 12, 13, 14, 15},
            {16, 17, 18, 19, 20},
            {21, 22, 23, 24, 25}
        };
        
        assertTrue( ! MatrixManipulator.addable(mat1, mat2) );
    }
    
    @Test
    public void testAdd()
    {
        int[][] mat1 = {
                { 1, 2, 3, 4, 5 },
                { 6, 7, 8, 9, 10 }
        };
        
        int[][] mat2 = {
                {11, 12, 13, 14, 15},
                {16, 17, 18, 19, 20}
        };
        
        assertArrayEquals(new int[][] {
            {12, 14, 16, 18, 20},
            {22, 24, 26, 28, 30}},
            MatrixManipulator.add(mat1, mat2));
    }

    @Test
    public void testMultiplyByScalar()
    {
        int[][] mat = {
                {1, 2, 3, 4, 5},
                {6, 7, 8, 9, 10}
        };
        
        assertArrayEquals(new int[][] {
            {2, 4, 6, 8, 10},
            {12, 14, 16, 18, 20}},
            MatrixManipulator.multiplyByScalar(2, mat));
    }

    @Test
    public void testMultipliable()
    {
        int[][] mat1 = {
                {20, 21, 22, 23},
                {24, 25, 26, 27},
                {28, 29, 30, 31}
        };
        
        int[][] mat2 = {
                {32, 33},
                {34, 35},
                {36, 37},
                {38, 39}
        };
        
        assertTrue(MatrixManipulator.multipliable(mat1, mat2));
        
        
        mat2 = new int[][]{
                {32, 33, 36},
                {34, 35, 37},
                {36, 37, 38},
                {38, 39, 39}
        };
        
        assertTrue(MatrixManipulator.multipliable(mat1, mat2));
        
        
        mat2 = new int[][]{
                {32, 33, 36},
                {34, 35, 37},
                {36, 37, 38},
                {38, 39, 39},
                {40, 41, 42}
        };
        
        assertTrue( ! MatrixManipulator.multipliable(mat1, mat2) );
    }
    
    @Test
    public void testMultiplyWithIndexes()
    {
        int[][] mat1 = {
                {20, 21, 22, 23},
                {24, 25, 26, 27},
                {28, 29, 30, 31}
        };
        
        int[][] mat2 = {
                {32, 33},
                {34, 35},
                {36, 37},
                {38, 39}
        };
        
        assertEquals(3020, MatrixManipulator.multiply(mat1, 0, mat2, 0));
        assertEquals(3106, MatrixManipulator.multiply(mat1, 0, mat2, 1));
        assertEquals(3580, MatrixManipulator.multiply(mat1, 1, mat2, 0));
        assertEquals(3682, MatrixManipulator.multiply(mat1, 1, mat2, 1));
    }

    @Test
    public void testMultiply()
    {
        int[][] mat1 = {
                {20, 21, 22, 23},
                {24, 25, 26, 27},
                {28, 29, 30, 31}
        };
        
        int[][] mat2 = {
                {32, 33},
                {34, 35},
                {36, 37},
                {38, 39}
        };
        
        assertArrayEquals(new int[][] {
            {3020, 3106},
            {3580, 3682},
            {4140, 4258}},
            MatrixManipulator.multiply(mat1, mat2));
    }
}
