#include <gtest/gtest.h>
#include "DObject.h"
#include "Metadata.h"

/**
 * @file DObjectTest.cpp
 * @brief Unit tests for the DObject class.
 */

/**
 * @brief Test suite for the DObject class.
 */
class DObjectTest : public ::testing::Test {
protected:
    DObject defaultObject;
    DObject initializedObject;

    void SetUp() override {
        // Create a DObject with initial data and metadata
        DObject initializedObject(std::vector<float>{1.0f, 2.0f, 3.0f, 4.0f});
    }
};

/**
 * @test Verify default constructor initializes correctly.
 */
TEST_F(DObjectTest, DefaultConstructor) {
    EXPECT_NO_THROW(DObject());
    EXPECT_NO_THROW(auto data = defaultObject.getData());
    EXPECT_FALSE(defaultObject.isDebuggingEnabled());
}

/**
 * @test Verify constructor initializes with provided data and metadata.
 */
TEST_F(DObjectTest, ParameterizedConstructor) {
    DObject obj(std::vector<int>{1, 2, 3});

    EXPECT_NO_THROW(obj.getData());
    EXPECT_EQ(std::get<std::vector<int>>(obj.getData()), std::vector<int>({1, 2, 3}));
}

/**
 * @test Verify getter and setter for data.
 */
TEST_F(DObjectTest, DataSetterGetter) {
    std::vector<double> newData = {3.14, 2.71, 1.61};
    EXPECT_NO_THROW(defaultObject.setData(newData));
    EXPECT_EQ(std::get<std::vector<double>>(defaultObject.getData()), newData);
}

/**
 * @test Verify enabling and disabling debugging.
 */
TEST_F(DObjectTest, DebuggingFlag) {
    EXPECT_FALSE(defaultObject.isDebuggingEnabled());
    defaultObject.setDebugging(true);
    EXPECT_TRUE(defaultObject.isDebuggingEnabled());
    defaultObject.setDebugging(false);
    EXPECT_FALSE(defaultObject.isDebuggingEnabled());
}

TEST_F(DObjectTest, ErrorCodeSetteGetter) {
  int prevCode;
  prevCode = defaultObject.setErrorCode(1);
  EXPECT_EQ(prevCode, 0);
  prevCode = defaultObject.setErrorCode(2);
  EXPECT_EQ(prevCode, 1);
  int getCode;
  getCode = defaultObject.getErrorCode();
  EXPECT_EQ(getCode, 2);
}

/**
 * @test Basic Integration Test
 */
TEST_F(DObjectTest, IntegrationTest) {
    float data = 55.86868;
    DObject obj;
    obj.setData(data);
    float newData;
    newData = std::get<float>(obj.getData());
    EXPECT_EQ(data, newData);
}


