#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 = reinterpret_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 = reinterpret_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 = reinterpret_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);
}