//
// Created by xfj12 on 2025/3/25.
//
#include <gtest/gtest.h>
#include <solution/2711.h>

class DifferenceOfDistinctValuesTest : public ::testing::Test
{
  protected:
    void SetUp() override
    {
    }
    void TearDown() override
    {
    }
};

TEST_F(DifferenceOfDistinctValuesTest, HandlesExpectedOutput)
{
    int gridSize = 6;
    int gridColSize[] = {10, 10, 10, 10, 10, 10};
    int *grid[6];
    int data[6][10] = {{6, 28, 16, 15, 35, 19, 38, 42, 32, 27}, {8, 49, 38, 16, 6, 9, 12, 11, 10, 6},
                       {16, 32, 46, 17, 15, 29, 5, 47, 48, 33}, {25, 12, 34, 21, 8, 15, 3, 3, 7, 38},
                       {32, 23, 9, 30, 35, 27, 10, 5, 12, 18},  {11, 2, 48, 22, 43, 26, 25, 1, 20, 19}};

    for (int i = 0; i < gridSize; i++)
    {
        grid[i] = data[i];
    }

    int returnSize;
    int *returnColumnSizes;
    int **result = differenceOfDistinctValues(grid, gridSize, gridColSize, &returnSize, &returnColumnSizes);

    int expected[6][10] = {{5, 5, 4, 5, 5, 4, 3, 2, 1, 0}, {4, 3, 3, 2, 3, 3, 2, 1, 0, 1},
                           {3, 2, 1, 1, 2, 1, 1, 0, 1, 2}, {2, 1, 0, 1, 1, 0, 1, 1, 2, 3},
                           {1, 0, 1, 2, 3, 3, 1, 3, 3, 4}, {0, 1, 2, 3, 4, 5, 5, 3, 5, 5}};

    ASSERT_EQ(returnSize, gridSize);
    for (int i = 0; i < gridSize; i++)
    {
        ASSERT_EQ(returnColumnSizes[i], 10);
        for (int j = 0; j < 10; j++)
        {
            ASSERT_EQ(result[i][j], expected[i][j]);
        }
    }

    for (int i = 0; i < returnSize; i++)
    {
        free(result[i]);
    }
    free(result);
    free(returnColumnSizes);
}

TEST_F(DifferenceOfDistinctValuesTest, HandlesSmallGrid)
{
    int gridSize = 3;
    int gridColSize[] = {3, 3, 3};
    int *grid[3];
    int data[3][3] = {{1, 2, 3}, {3, 1, 5}, {3, 2, 1}};

    for (int i = 0; i < gridSize; i++)
    {
        grid[i] = data[i];
    }

    int returnSize;
    int *returnColumnSizes;
    int **result = differenceOfDistinctValues(grid, gridSize, gridColSize, &returnSize, &returnColumnSizes);

    int expected[3][3] = {{1, 1, 0}, {1, 0, 1}, {0, 1, 1}};

    ASSERT_EQ(returnSize, gridSize);
    for (int i = 0; i < gridSize; i++)
    {
        ASSERT_EQ(returnColumnSizes[i], 3);
        for (int j = 0; j < 3; j++)
        {
            ASSERT_EQ(result[i][j], expected[i][j]);
        }
    }

    for (int i = 0; i < returnSize; i++)
    {
        free(result[i]);
    }
    free(result);
    free(returnColumnSizes);
}
