public class FlagTester
{
    public static void main(String[] args)
    {
        int passedTier1 = 0;
        int passedTier2 = 0;

        System.out.println("========================================");
        System.out.println("       RUNNING FLAG TESTING SUITE       ");
        System.out.println("========================================");

        // =====================================================================
        // TIER 1: STANDARD DIMENSIONS (Perfect Multiples of 3)
        // Goal: Verify base loop logic and nested conditional choices.
        // =====================================================================
        System.out.println("\n--- TIER 1: Standard Clean Dimensions (Divisible by 3) ---");

        if (testMatrix("French Flag [3 Rows x 3 Columns]", FlagCanvas.frenchFlag(3, 3), getFrench3x3())) { passedTier1++; }
        if (testMatrix("Italian Flag [6 Rows x 3 Columns]", FlagCanvas.italianFlag(3, 6), getItalian6x3())) { passedTier1++; }
        if (testMatrix("German Flag [3 Rows x 6 Columns]", FlagCanvas.germanFlag(6, 3), getGerman3x6())) { passedTier1++; }
        if (testMatrix("Armenian Flag [6 Rows x 6 Columns]", FlagCanvas.armenianFlag(6, 6), getArmenian6x6())) { passedTier1++; }
        
        char[][] austria3x6 = FlagCanvas.drawHorizontalThreeStripe(6, 3, 'R', 'W', 'R');
        if (testMatrix("Austria Flag [3 Rows x 6 Columns]", austria3x6, getAustria3x6())) { passedTier1++; }


        // =====================================================================
        // TIER 2: PATHOLOGICAL DIMENSIONS (Indivisible by 3)
        // Goal: Verify that the final 'else' statement absorbs leftover coordinates.
        // =====================================================================
        System.out.println("\n--- TIER 2: Pathological Dimensions (Indivisible Remainder Checks) ---");

        // Width 4 / 3 = stripe width 1. Column index 3 spills over to the last stripe.
        if (testMatrix("French Flag [3 Rows x 4 Columns]", FlagCanvas.frenchFlag(4, 3), getFrench3x4Pathological())) { passedTier2++; }
        
        // Width 5 / 3 = stripe width 1. Column indices 3 and 4 spill over to the last stripe.
        if (testMatrix("Italian Flag [3 Rows x 5 Columns]", FlagCanvas.italianFlag(5, 3), getItalian3x5Pathological())) { passedTier2++; }
        
        // Height 4 / 3 = stripe height 1. Row index 3 spills over to the last stripe.
        if (testMatrix("German Flag [4 Rows x 3 Columns]", FlagCanvas.germanFlag(3, 4), getGerman4x3Pathological())) { passedTier2++; }
        
        // Height 5 / 3 = stripe height 1. Row indices 3 and 4 spill over to the last stripe.
        if (testMatrix("Armenian Flag [5 Rows x 3 Columns]", FlagCanvas.armenianFlag(3, 5), getArmenian5x3Pathological())) { passedTier2++; }
        
        // Height 5 / 3 = stripe height 1. Row indices 3 and 4 spill over to the last stripe.
        char[][] austria5x3 = FlagCanvas.drawHorizontalThreeStripe(3, 5, 'R', 'W', 'R');
        if (testMatrix("Austria Flag [5 Rows x 3 Columns]", austria5x3, getAustria5x3Pathological())) { passedTier2++; }


        // =====================================================================
        // PERFORMANCE SUMMARY
        // =====================================================================
        System.out.println("\n========================================");
        System.out.println("            GRADING SUMMARY             ");
        System.out.println("========================================");
        System.out.println("TIER 1 (Clean Divisions): " + passedTier1 + " / 5 Passed");
        System.out.println("TIER 2 (Uneven Remainders): " + passedTier2 + " / 5 Passed");
        System.out.println("TOTAL SCORE:              " + (passedTier1 + passedTier2) + " / 10");
        System.out.println("========================================");
    }

    private static boolean testMatrix(String testName, char[][] actual, char[][] expected)
    {
        if (actual == null)
        {
            System.out.println("[FAIL] " + testName + " -> Array is null.");
            return false;
        }
        if (actual.length != expected.length || actual[0].length != expected[0].length)
        {
            System.out.println("[FAIL] " + testName + " -> Dimension mismatch. Expected " 
                               + expected.length + "x" + expected[0].length + ", got " 
                               + actual.length + "x" + actual[0].length);
            return false;
        }

        for (int r = 0; r < expected.length; r++)
        {
            for (int c = 0; c < expected[r].length; c++)
            {
                if (actual[r][c] != expected[r][c])
                {
                    System.out.println("[FAIL] " + testName + " -> Error at row " + r + ", col " + c 
                                       + ". Expected '" + expected[r][c] + "', got '" + actual[r][c] + "'");
                    return false;
                }
            }
        }
        System.out.println("[PASS] " + testName);
        return true;
    }

    // =========================================================================
    // EXPECTED MATRIX SOLUTIONS (Rows x Columns)
    // =========================================================================

    // --- Tier 1 Matrices (Perfect Clean Splits) ---
    private static char[][] getFrench3x3() { return new char[][] {{'B', 'W', 'R'}, {'B', 'W', 'R'}, {'B', 'W', 'R'}}; }
    private static char[][] getItalian6x3() { return new char[][] {{'G', 'W', 'R'}, {'G', 'W', 'R'}, {'G', 'W', 'R'}, {'G', 'W', 'R'}, {'G', 'W', 'R'}, {'G', 'W', 'R'}}; }
    private static char[][] getGerman3x6() { return new char[][] {{'K', 'K', 'K', 'K', 'K', 'K'}, {'R', 'R', 'R', 'R', 'R', 'R'}, {'Y', 'Y', 'Y', 'Y', 'Y', 'Y'}}; }
    private static char[][] getArmenian6x6() { return new char[][] {{'R', 'R', 'R', 'R', 'R', 'R'}, {'R', 'R', 'R', 'R', 'R', 'R'}, {'B', 'B', 'B', 'B', 'B', 'B'}, {'B', 'B', 'B', 'B', 'B', 'B'}, {'O', 'O', 'O', 'O', 'O', 'O'}, {'O', 'O', 'O', 'O', 'O', 'O'}}; }
    private static char[][] getAustria3x6() { return new char[][] {{'R', 'R', 'R', 'R', 'R', 'R'}, {'W', 'W', 'W', 'W', 'W', 'W'}, {'R', 'R', 'R', 'R', 'R', 'R'}}; }

    // --- Tier 2 Matrices (Strict Pathological Remainder Splits) ---
    private static char[][] getFrench3x4Pathological()
    {
        return new char[][] {
            {'B', 'W', 'R', 'R'}, // Last stripe captures column 2 and column 3
            {'B', 'W', 'R', 'R'},
            {'B', 'W', 'R', 'R'}
        };
    }

    private static char[][] getItalian3x5Pathological()
    {
        return new char[][] {
            {'G', 'W', 'R', 'R', 'R'}, // Last stripe stretches to capture columns 2, 3, 4
            {'G', 'W', 'R', 'R', 'R'},
            {'G', 'W', 'R', 'R', 'R'}
        };
    }

    private static char[][] getGerman4x3Pathological()
    {
        return new char[][] {
            {'K', 'K', 'K'}, // Row 0
            {'R', 'R', 'R'}, // Row 1
            {'Y', 'Y', 'Y'}, // Row 2
            {'Y', 'Y', 'Y'}  // Row 3 (Caught by the else block)
        };
    }

    private static char[][] getArmenian5x3Pathological()
    {
        return new char[][] {
            {'R', 'R', 'R'}, // Row 0
            {'B', 'B', 'B'}, // Row 1
            {'O', 'O', 'O'}, // Row 2
            {'O', 'O', 'O'}, // Row 3 (Caught by the else block)
            {'O', 'O', 'O'}  // Row 4 (Caught by the else block)
        };
    }

    private static char[][] getAustria5x3Pathological()
    {
        return new char[][] {
            {'R', 'R', 'R'}, // Row 0
            {'W', 'W', 'W'}, // Row 1
            {'R', 'R', 'R'}, // Row 2
            {'R', 'R', 'R'}, // Row 3 (Caught by the else block)
            {'R', 'R', 'R'}  // Row 4 (Caught by the else block)
        };
    }
}