/*********************************************************************
 * \file   Caster.cpp
 *
 * \author Romain BOULLARD
 * \date   October 2025
 *********************************************************************/
#include <Utils/Caster.hpp>

#include <gtest/gtest.h>

namespace Bigfoot
{
class Parent
{
  public:
    Parent(const std::uint32_t p_value):
        m_value(p_value)
    {
    }

    virtual ~Parent() = default;

    std::uint32_t GetParentValue() const
    {
        return m_value;
    }

    virtual std::uint32_t GetChildValue() const = 0;

  private:
    std::uint32_t m_value;
};

/****************************************************************************************/

class ChildA final: public Parent
{
  public:
    ChildA(const std::uint32_t p_value):
        Parent(28),
        m_value(p_value)
    {
    }

    ~ChildA() override = default;

    std::uint32_t GetChildValue() const override
    {
        return m_value;
    }

  private:
    std::uint32_t m_value;
};

/****************************************************************************************/

class ChildB final: public Parent
{
  public:
    ChildB(const std::uint32_t p_value):
        Parent(34),
        m_value(p_value)
    {
    }

    ~ChildB() override = default;

    std::uint32_t GetChildValue() const override
    {
        return m_value;
    }

  private:
    std::uint32_t m_value;
};

/****************************************************************************************/

class CasterFixture: public ::testing::Test
{
  protected:
    std::unique_ptr<Parent> m_a = std::make_unique<ChildA>(42);
    ChildB m_b {12};
};

/****************************************************************************************/

TEST_F(CasterFixture, ObjectCast)
{
    EXPECT_EQ(m_a->GetParentValue(), 28);
    EXPECT_EQ(m_a->GetChildValue(), 42);
    const ChildA* child = BIGFOOT_OBJECT_CAST(ChildA, m_a.get());
    EXPECT_EQ(child->GetParentValue(), 28);
    EXPECT_EQ(child->GetChildValue(), 42);

    EXPECT_EQ(m_b.GetParentValue(), 34);
    EXPECT_EQ(m_b.GetChildValue(), 12);
    const Parent& parent = BIGFOOT_OBJECT_CAST(Parent, m_b);
    EXPECT_EQ(parent.GetParentValue(), 34);
}
}   // namespace Bigfoot
