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