#include "Base/Axis/MakeScale.h"
#include "Base/Axis/Scale.h"
#include "Device/Data/ArrayUtil.h"
#include "Device/Data/Datafield.h"
#include "Tests/GTestWrapper/google_test.h"
#include <vector>

TEST(ArrayUtilsTest, DatafieldFromVector1D)
{
    // double
    const std::vector<double> vec_double = {10.0, 20.0, 30.0, 40.0};
    auto data1 = DataUtil::Array::createPField1D(vec_double);

    EXPECT_EQ(data1->size(), vec_double.size());
    EXPECT_EQ(data1->flatVector(), vec_double);
    EXPECT_EQ(data1->axis(0).min(), 0.0);
    EXPECT_EQ(data1->axis(0).max(), 4.0);
}

TEST(ArrayUtilsTest, DatafieldToVector1D)
{
    const std::vector<double> expected = {10.0, 20.0, 30.0, 40.0};
    Datafield data({newEquiDivision("axis0", 4, 10.0, 20.0)});
    data.setVector(expected);

    auto vec = DataUtil::Array::createVector1D(data);

    EXPECT_EQ(vec.size(), data.size());
    EXPECT_EQ(vec, expected);
}

TEST(ArrayUtilsTest, DatafieldFromVector2D)
{
    const std::vector<std::vector<double>> vec_double = {
        {0.0, 1.0, 2.0, 3.0}, {4.0, 5.0, 6.0, 7.0}, {8.0, 9.0, 10.0, 11.0}};
    auto data = DataUtil::Array::createPField2D(vec_double);

    EXPECT_EQ(data->rank(), 2u);
    EXPECT_EQ(data->size(), 12u);
    EXPECT_EQ(data->axis(0).size(), 4u);
    EXPECT_EQ(data->axis(0).min(), 0.0);
    EXPECT_EQ(data->axis(0).max(), 4.0);
    EXPECT_EQ(data->axis(1).size(), 3u);
    EXPECT_EQ(data->axis(1).min(), 0.0);
    EXPECT_EQ(data->axis(1).max(), 3.0);

    const std::vector<double> expected = {8.0,  4.0, 0.0, 9.0,  5.0, 1.0,
                                          10.0, 6.0, 2.0, 11.0, 7.0, 3.0};

    EXPECT_EQ(data->flatVector(), expected);
}

TEST(ArrayUtilsTest, DatafieldToVector2D)
{
    Datafield data(
        {newEquiDivision("axis0", 4, 10.0, 20.0), newEquiDivision("axis1", 3, 30.0, 40.0)});
    const std::vector<double> values = {8.0,  4.0, 0.0, 9.0,  5.0, 1.0,
                                        10.0, 6.0, 2.0, 11.0, 7.0, 3.0};

    data.setVector(values);

    auto vec = DataUtil::Array::createVector2D(data);
    const std::vector<std::vector<double>> expected = {
        {0.0, 1.0, 2.0, 3.0}, {4.0, 5.0, 6.0, 7.0}, {8.0, 9.0, 10.0, 11.0}};
    EXPECT_EQ(vec, expected);
}
