import static org.junit.jupiter.api.Assertions.*;

import java.util.Arrays;

import org.junit.jupiter.api.Test;

public class TwoDArrayPracticeTest
{
    @Test
    public void testRowSwap()
    {
        int[][] mat = new int[][]{
            {10, 9, 8, 7},
            {6, 5, 4, 3},
            {2, 1, -1, 0}
        };
        
        int rowAIndex = 1, rowBIndex = 2;
        
        int[][] expectedResult = new int[][]{
            {10, 9, 8, 7},
            {2, 1, -1, 0},
            {6, 5, 4, 3}
        };
        
        TwoDArrayPractice.rowSwap(mat, rowAIndex, rowBIndex);
        assertTrue(Arrays.deepEquals(mat, expectedResult));
    }
    
    @Test
    public void testColSwap()
    {
        int[][] mat = new int[][]{
            {10, 9, 8, 7},
            {6, 5, 4, 3},
            {2, 1, -1, 0}
        };
        
        int colAIndex = 1, colBIndex = 3;
        
        int[][] expectedResult = new int[][]{
            {10, 7, 8, 9},
            {6, 3, 4, 5},
            {2, 0, -1, 1}
        };
        
        TwoDArrayPractice.colSwap(mat, colAIndex, colBIndex);
        assertTrue(Arrays.deepEquals(mat, expectedResult));
    }

    @Test
    public void testFillRowMajorExact()
    {
        String phrase = "stop whining";
        
        int numRows = 3, numCols = 4;
        
        String[][] expectedResult = {
                {"s", "t", "o", "p"},
                {" ", "w", "h", "i"},
                {"n", "i", "n", "g"}
        };
        
        String[][] actualResult = TwoDArrayPractice.fillRowMajor(
                phrase, numRows, numCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testFillRowMajorTooMany()
    {
        String phrase = "stop complaining";
        
        int numRows = 3, numCols = 4;
        
        String[][] expectedResult = {
                {"s", "t", "o", "p"},
                {" ", "c", "o", "m"},
                {"p", "l", "a", "i"}
        };
        
        String[][] actualResult = TwoDArrayPractice.fillRowMajor(
                phrase, numRows, numCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testFillRowMajorTooFew()
    {
        String phrase = "do more";
        
        int numRows = 3, numCols = 4;
        
        String[][] expectedResult = {
                {"d", "o", " ", "m"},
                {"o", "r", "e", null},
                {null, null, null, null}
        };
        
        String[][] actualResult = TwoDArrayPractice.fillRowMajor(
                phrase, numRows, numCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }

    @Test
    public void testFillColumnMajor()
    {
        int[] original = new int[] {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1};
        
        int numRows = 3, numCols = 4;
        
        int[][] expectedResult = new int[][]{
            {10, 7, 4, 1},
            {9, 6, 3, 0},
            {8, 5, 2, -1}
        };
        
        int[][] actualResult = TwoDArrayPractice.fillColumnMajor(
                original, numRows, numCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }

    @Test
    public void testFillDownUp()
    {
        int[] vals = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        
        int numRows = 3, numCols = 4;
        
        int[][] expectedResult = new int[][] {
            {1, 6, 7, 12},
            {2, 5, 8, 11},
            {3, 4, 9, 10}
        };
        
        int[][] actualResult = TwoDArrayPractice.fillDownUp(
                vals, numRows, numCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testGrow()
    {
        int[][] original = new int[][]{
            {10, 9, 8, 7},
            {6, 5, 4, 3},
            {2, 1, -1, 0}
        };
        
        int newRows = 4, newCols = 5;
        
        int[][] expectedResult = new int[][] {
            {10, 9, 8, 7, 6},
            {5, 4, 3, 2, 1},
            {-1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0}
        };
        
        int[][] actualResult = TwoDArrayPractice.grow(original, newRows, newCols);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testCrop()
    {
        int[][] original = new int[][]{
            {10, 9, 8, 7},
            {6, 5, 4, 3},
            {2, 1, -1, 0}
        };
        
        int startRow = 0, startCol = 1, endRow = 1, endCol = 2;
        
        int[][] expectedResult = new int[][] {
            {9, 8},
            {5, 4}
        };
        
        int[][] actualResult = TwoDArrayPractice.crop(original,
                startRow, startCol, endRow, endCol);
        
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testInvert()
    {
        int[][] mat = new int[][]{
            {10, 9, 8, 7},
            {6, 5, 4, 3},
            {2, 1, -1, 0}
        };
        
        int[][] expectedResult = new int[][]{
            {10, 6, 2},
            {9, 5, 1},
            {8, 4, -1},
            {7, 3, 0}
        };
        
        int[][] actualResult = TwoDArrayPractice.invert(mat);
        assertTrue(Arrays.deepEquals(actualResult, expectedResult));
    }
    
    @Test
    public void testConsolidate()
    {
        String[][] mat = {
                {"a", null, "b", "c", null},
                {null, "d", null, null, null},
                {"e", null, null, "f", null}
        };
        
        String[][] expectedResult = {
                {"a", "b", "c", "d", "e"},
                {"f", null, null, null, null},
                {null, null, null, null, null}
        };
        
        TwoDArrayPractice.consolidate(mat);
        assertTrue(Arrays.deepEquals(mat, expectedResult));
        
        
        mat = new String[][]{
                {"a", null, "b", "c", null},
                {null, "d", "e", null, "f"},
                {"g", "h", "i", "j", "k"}
        };
        
        expectedResult = new String[][]{
                {"a", "b", "c", "d", "e"},
                {"f", "g", "h", "i", "j"},
                {"k", null, null, null, null}
        };
        
        TwoDArrayPractice.consolidate(mat);
        assertTrue(Arrays.deepEquals(mat, expectedResult));
    }
}
