#include <rive/artboard.hpp>
#include <rive/file.hpp>
#include <rive/math/circle_constant.hpp>
#include <rive/node.hpp>
#include <rive/shapes/ellipse.hpp>
#include <rive/shapes/path_composer.hpp>
#include <rive/shapes/rectangle.hpp>
#include <rive/shapes/shape.hpp>
#include <utils/no_op_factory.hpp>
#include <utils/no_op_renderer.hpp>
#include <catch.hpp>
#include <cstdio>

// Need a specialized "noop" factory that does make an inspectable Path

namespace
{
enum class TestPathCommandType
{
    MoveTo,
    LineTo,
    CubicTo,
    Reset,
    Close
};

struct TestPathCommand
{
    TestPathCommandType command;
    float x;
    float y;
    float inX;
    float inY;
    float outX;
    float outY;
};

class TestRenderPath : public rive::RenderPath
{
public:
    std::vector<TestPathCommand> commands;
    void reset() override
    {
        commands.emplace_back(
            TestPathCommand{TestPathCommandType::Reset, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
    }

    void fillRule(rive::FillRule value) override {}
    void addPath(rive::CommandPath* path, const rive::Mat2D& transform) override {}
    void addRenderPath(rive::RenderPath* path, const rive::Mat2D& transform) override {}

    void moveTo(float x, float y) override
    {
        commands.emplace_back(
            TestPathCommand{TestPathCommandType::MoveTo, x, y, 0.0f, 0.0f, 0.0f, 0.0f});
    }
    void lineTo(float x, float y) override
    {
        commands.emplace_back(
            TestPathCommand{TestPathCommandType::LineTo, x, y, 0.0f, 0.0f, 0.0f, 0.0f});
    }
    void cubicTo(float ox, float oy, float ix, float iy, float x, float y) override
    {
        commands.emplace_back(TestPathCommand{TestPathCommandType::CubicTo, x, y, ix, iy, ox, oy});
    }
    void close() override
    {
        commands.emplace_back(
            TestPathCommand{TestPathCommandType::Close, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
    }
};

class TestNoOpFactory : public rive::NoOpFactory
{
public:
    std::unique_ptr<rive::RenderPath> makeEmptyRenderPath() override
    {
        return std::make_unique<TestRenderPath>();
    }
};
} // namespace

TEST_CASE("rectangle path builds expected commands", "[path]")
{
    TestNoOpFactory emptyFactory;
    rive::Artboard artboard(&emptyFactory);
    rive::Shape* shape = new rive::Shape();
    rive::Rectangle* rectangle = new rive::Rectangle();

    rectangle->x(0.0f);
    rectangle->y(0.0f);
    rectangle->width(100.0f);
    rectangle->height(200.0f);
    rectangle->cornerRadiusTL(0.0f);

    artboard.addObject(&artboard);
    artboard.addObject(shape);
    artboard.addObject(rectangle);
    rectangle->parentId(1);

    REQUIRE(artboard.initialize() == rive::StatusCode::Ok);

    artboard.advance(0.0f);

    REQUIRE(rectangle->commandPath() != nullptr);

    auto path = static_cast<TestRenderPath*>(rectangle->commandPath());

    REQUIRE(path->commands.size() == 7);
    REQUIRE(path->commands[0].command == TestPathCommandType::Reset);
    REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo);
    REQUIRE(path->commands[2].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[3].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[4].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[5].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[6].command == TestPathCommandType::Close);
}

TEST_CASE("rounded rectangle path builds expected commands", "[path]")
{
    TestNoOpFactory emptyFactory;
    rive::Artboard artboard(&emptyFactory);
    rive::Shape* shape = new rive::Shape();
    rive::Rectangle* rectangle = new rive::Rectangle();

    rectangle->x(0.0f);
    rectangle->y(0.0f);
    rectangle->width(100.0f);
    rectangle->height(200.0f);
    rectangle->cornerRadiusTL(20.0f);
    rectangle->linkCornerRadius(true);

    artboard.addObject(&artboard);
    artboard.addObject(shape);
    artboard.addObject(rectangle);
    rectangle->parentId(1);

    artboard.initialize();

    artboard.advance(0.0f);

    REQUIRE(rectangle->commandPath() != nullptr);

    auto path = static_cast<TestRenderPath*>(rectangle->commandPath());

    // reset
    // moveTo
    // cubic - for 1st corner

    // lineTo, cubicTo for 2nd corner
    // lineTo, cubicTo for 3rd corner
    // lineTo, cubicTo for 4th corner

    // close

    REQUIRE(path->commands.size() == 11);

    // Init
    REQUIRE(path->commands[0].command == TestPathCommandType::Reset);
    REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo);

    // 1st
    REQUIRE(path->commands[2].command == TestPathCommandType::CubicTo);

    // 2nd
    REQUIRE(path->commands[3].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[4].command == TestPathCommandType::CubicTo);

    // 3rd
    REQUIRE(path->commands[5].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[6].command == TestPathCommandType::CubicTo);

    // 4th
    REQUIRE(path->commands[7].command == TestPathCommandType::LineTo);
    REQUIRE(path->commands[8].command == TestPathCommandType::CubicTo);

    REQUIRE(path->commands[9].command == TestPathCommandType::LineTo);

    REQUIRE(path->commands[10].command == TestPathCommandType::Close);
}

TEST_CASE("ellipse path builds expected commands", "[path]")
{
    TestNoOpFactory emptyFactory;
    rive::Artboard artboard(&emptyFactory);
    rive::Ellipse* ellipse = new rive::Ellipse();
    rive::Shape* shape = new rive::Shape();

    ellipse->x(0.0f);
    ellipse->y(0.0f);
    ellipse->width(100.0f);
    ellipse->height(200.0f);

    artboard.addObject(&artboard);
    artboard.addObject(shape);
    artboard.addObject(ellipse);
    ellipse->parentId(1);

    artboard.initialize();

    artboard.advance(0.0f);

    REQUIRE(ellipse->commandPath() != nullptr);

    auto path = static_cast<TestRenderPath*>(ellipse->commandPath());

    // reset
    // moveTo
    // cubic - for 1st corner

    // lineTo, cubicTo for 2nd corner
    // lineTo, cubicTo for 3rd corner
    // lineTo, cubicTo for 4th corner

    // close

    REQUIRE(path->commands.size() == 7);

    // Init
    REQUIRE(path->commands[0].command == TestPathCommandType::Reset);
    REQUIRE(path->commands[1].command == TestPathCommandType::MoveTo);
    REQUIRE(path->commands[1].x == 0.0f);
    REQUIRE(path->commands[1].y == -100.0f);

    // 1st
    REQUIRE(path->commands[2].command == TestPathCommandType::CubicTo);
    REQUIRE(path->commands[2].outX == 50.0f * rive::circleConstant);
    REQUIRE(path->commands[2].outY == -100.0f);
    REQUIRE(path->commands[2].inX == 50.0f);
    REQUIRE(path->commands[2].inY == -100.0f * rive::circleConstant);
    REQUIRE(path->commands[2].x == 50.0f);
    REQUIRE(path->commands[2].y == 0.0f);

    // 2nd
    REQUIRE(path->commands[3].command == TestPathCommandType::CubicTo);
    REQUIRE(path->commands[3].outX == 50.0f);
    REQUIRE(path->commands[3].outY == 100.0f * rive::circleConstant);
    REQUIRE(path->commands[3].inX == 50.0f * rive::circleConstant);
    REQUIRE(path->commands[3].inY == 100.0f);
    REQUIRE(path->commands[3].x == 0.0f);
    REQUIRE(path->commands[3].y == 100.0f);

    // 3rd
    REQUIRE(path->commands[4].command == TestPathCommandType::CubicTo);
    REQUIRE(path->commands[4].outX == -50.0f * rive::circleConstant);
    REQUIRE(path->commands[4].outY == 100.0f);
    REQUIRE(path->commands[4].inX == -50.0f);
    REQUIRE(path->commands[4].inY == 100.0f * rive::circleConstant);
    REQUIRE(path->commands[4].x == -50.0f);
    REQUIRE(path->commands[4].y == 0.0f);

    // 4th
    REQUIRE(path->commands[5].command == TestPathCommandType::CubicTo);
    REQUIRE(path->commands[5].outX == -50.0f);
    REQUIRE(path->commands[5].outY == -100.0f * rive::circleConstant);
    REQUIRE(path->commands[5].inX == -50.0f * rive::circleConstant);
    REQUIRE(path->commands[5].inY == -100.0f);
    REQUIRE(path->commands[5].x == 0.0f);
    REQUIRE(path->commands[5].y == -100.0f);

    REQUIRE(path->commands[6].command == TestPathCommandType::Close);
}
