/*
 * Copyright 2025 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkPathBuilder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkTypes.h"
#include "include/private/SkFixed.h"
#include "src/core/SkEdge.h"
#include "src/core/SkEdgeBuilder.h"
#include "src/core/SkGeometry.h"
#include "tests/Test.h"

#include <cstddef>

DEF_TEST(SkEdge_CWLineWithoutClip_PublicMembersMatchMathematics, r) {
    SkEdge e;
    e.setLine({0, 4}, {10, 20});

    REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCW);
    // The slope of X with respect to Y of this line segment is (10 - 0) / (20 - 4) or 0.625
    REPORTER_ASSERT(r, e.fDxDy == SkFloatToFixed(0.625f));
    // The Y coordinate conceptually starts at 0.5, so make sure the X coordinate matches is
    // 0.5 * 0.625 (the slope)
    REPORTER_ASSERT(r, e.fX == SkFloatToFixed(0.3125f));
    // Even though these are stored as integers, they conceptually represent the midpoint of
    // the line (4.5 and 19.5).
    REPORTER_ASSERT(r, e.fFirstY == 4);
    REPORTER_ASSERT(r, e.fLastY == 19);
    // Lines are "approximated" in one shot and have no need for follow-up approximations.
    REPORTER_ASSERT(r, !e.hasNextSegment());
}

DEF_TEST(SkEdge_CWLineNullClip_PublicMembersMatchMathematics, r) {
    SkEdge e;
    e.setLine({0, 4}, {10, 20}, nullptr);

    REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCW);
    // The slope of X with respect to Y of this line segment is (10 - 0) / (20 - 4) or 0.625
    REPORTER_ASSERT(r, e.fDxDy == SkFloatToFixed(0.625f));
    // The Y coordinate conceptually starts at 0.5, so make sure the X coordinate matches is
    // 0.5 * 0.625 (the slope)
    REPORTER_ASSERT(r, e.fX == SkFloatToFixed(0.3125f));
    // Even though these are stored as integers, they conceptually represent the midpoint of
    // the line (4.5 and 19.5).
    REPORTER_ASSERT(r, e.fFirstY == 4);
    REPORTER_ASSERT(r, e.fLastY == 19);
    // Lines are "approximated" in one shot and have no need for follow-up approximations.
    REPORTER_ASSERT(r, !e.hasNextSegment());
}

DEF_TEST(SkEdge_CCWLineWithoutClip_PublicMembersMatchMathematics, r) {
    SkEdge e;
    e.setLine({0, -4}, {10, -20});
    REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCCW);
    // The slope of X with respect to Y of this line segment is (10 - 0) / (-20 - -4) or -0.625
    REPORTER_ASSERT(r, e.fDxDy == SkFloatToFixed(-0.625f));
    // The Y coordinate conceptually starts at 0.5, so make sure the X coordinate matches is
    // 10 + 0.5 * -0.625 (the slope)
    REPORTER_ASSERT(r, e.fX == SkFloatToFixed(9.6875f));
    // Even though these are stored as integers, they conceptually represent the midpoint of
    // the line (-19.5 and -4.5).
    REPORTER_ASSERT(r, e.fFirstY == -20);
    REPORTER_ASSERT(r, e.fLastY == -5);
    REPORTER_ASSERT(r, !e.hasNextSegment());
}

static float quad_slope_at(const SkPoint pts[3], float t) {
    SkASSERT(t >= 0.0f && t <= 1.0f);
    // A quadratic Bezier curve can be written in polynomial form as
    //   Q(t) = At^2 + Bt + C
    // Where A = p0 - 2p1 + p2, B = 2(p1 - p0), C = p0
    // and p0 is the start point, p2 is the end point and p1 is the control point.
    // With some derivatives and algebra, the slope of X with respect to Y is
    // ((2*x0 - 4*x1 + 2*x2)t + (2*x1 - 2*x0)) / (2*y0 - 4*y1 + 2*y2)*t + (2*y1 - 2*y0)
    const float x0 = pts[0].fX, x1 = pts[1].fX, x2 = pts[2].fX;
    const float dxdt = (2 * x0 - 4 * x1 + 2 * x2) * t + (2 * x1 - 2 * x0);
    const float y0 = pts[0].fY, y1 = pts[1].fY, y2 = pts[2].fY;
    const float dydt = (2 * y0 - 4 * y1 + 2 * y2) * t + (2 * y1 - 2 * y0);
    return dxdt / dydt;
}

static float cubic_slope_at(const SkPoint pts[4], float t) {
    SkASSERT(t >= 0.0f && t <= 1.0f);
    // A cubic Bezier curve can be written in polynomial form as
    //   C(t) = At^3 + Bt^2 + Ct + D
    // Where A = -p0 + 3p1 + -3p2 + p3
    //       B = 3p0 - 6p1 + 3p2
    //       C = -3p0 + 3p1
    //       D = p0
    // and p0 is the start point, p3 is the end point and p1/p2 are the control points.
    // With some derivatives and algebra, the slope of X with respect to Y is
    //  ((-3*x0 + 9*x1 + -9*x2 + 3*x3)*t*t + (6*x0 - 12*x1 + 6*x2)*t + (-3*x0 + 3*x1)) /
    //  ((-3*y0 + 9*y1 + -9*y2 + 3*y3)*t*t + (6*y0 - 12*y1 + 6*y2)*t + (-3*y0 + 3*y1))
    //
    const float x0 = pts[0].fX, x1 = pts[1].fX, x2 = pts[2].fX, x3 = pts[3].fX;
    const float dxdt = (-3 * x0 + 9 * x1 + -9 * x2 + 3 * x3) * t * t +
                       (6 * x0 - 12 * x1 + 6 * x2) * t + (-3 * x0 + 3 * x1);
    const float y0 = pts[0].fY, y1 = pts[1].fY, y2 = pts[2].fY, y3 = pts[3].fY;
    const float dydt = (-3 * y0 + 9 * y1 + -9 * y2 + 3 * y3) * t * t +
                       (6 * y0 - 12 * y1 + 6 * y2) * t + (-3 * y0 + 3 * y1);
    return dxdt / dydt;
}

static void assert_within_n_percent(skiatest::Reporter* r,
                                    float actual,
                                    float expected,
                                    float delta) {
    // Make sure we are passing in something like 5% and not 0.05
    SkASSERT(delta >= 1 && delta <= 25);
    float percentDiff = (std::abs(actual - expected) / expected);
    REPORTER_ASSERT(r, percentDiff < (delta / 100.f),
                    "%g was not within %g%% of %g",
                    actual, delta, expected);
}

static float eval_x_at(const SkQuadCoeff& quad, float t) { return quad.eval({t, t})[0]; }

static float eval_y_at(const SkQuadCoeff& quad, float t) { return quad.eval({t, t})[1]; }

static float eval_x_at(const SkCubicCoeff& cubic, float t) { return cubic.eval({t, t})[0]; }

static float eval_y_at(const SkCubicCoeff& cubic, float t) { return cubic.eval({t, t})[1]; }

DEF_TEST(SkEdge_Quad_ApproximatedWithMultipleLineSegments, r) {
    SkQuadraticEdge e;
    const SkPoint points[3] = {{0.f, 0.f}, {2.5f, 15.f}, {10.f, 20.f}};
    REPORTER_ASSERT(r, e.setQuadratic(points));

    const SkQuadCoeff exact = SkQuadCoeff(points);
    auto assert_x_on_curve_between = [&](SkFixed x, float tLower, float tUpper) {
        const float lower = eval_x_at(exact, tLower);
        const float upper = eval_x_at(exact, tUpper);
        REPORTER_ASSERT(r, SkFixedToFloat(x) >= lower && SkFixedToFloat(x) < upper,
                        "%g was not in [%g, %g]",
                        SkFixedToFloat(x),
                        lower,
                        upper);
    };
    auto assert_y_starts_at = [&](int32_t y, float atT) {
        const float start = sk_float_round2int(eval_y_at(exact, atT));
        REPORTER_ASSERT(r, y == start, "%d was not %g", y, start);
    };
    auto assert_y_ends_at = [&](int32_t y, float atT) {
        const float end = sk_float_round2int(eval_y_at(exact, atT)) - 1;  // this range is exclusive
        REPORTER_ASSERT(r, y == end, "%d was not %g", y, end);
    };

    // SkQuadraticEdge will approximate a quadratic Bezier curve with N line segments.
    // There are some heuristics to determine how many segments to use. For this curve, there are
    // 4 total segments - the current segment followed by 3 more.
    const int kNumSegments = 4;
    const float kSegmentWidth = 1.0f / kNumSegments;
    float t = 0.0f;
    for (int segments = kNumSegments - 1; segments >= 0; segments--) {
        skiatest::ReporterContext ctx(r,
                                      SkStringPrintf("Segment %d, t is [%g, %g]",
                                                     kNumSegments - segments - 1,
                                                     t,
                                                     t + kSegmentWidth));
        REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCW);
        REPORTER_ASSERT(r, e.segmentsLeft() == segments);

        // The slope for a line segment should be close to the curve at the midpoint between this
        // section of curve. e.g. for the segment [0.0, 0.25], it should be the slope at t=0.125
        const float segment1Slope = quad_slope_at(points, kSegmentWidth / 2 + t);
        assert_within_n_percent(r, SkFixedToFloat(e.fDxDy), segment1Slope, 1);

        // The x value could vary a bit depending on implementation and rounding
        assert_x_on_curve_between(e.fX, t, t + kSegmentWidth);

        // The start and stopping y values should match the actual curve.
        assert_y_starts_at(e.fFirstY, t);
        assert_y_ends_at(e.fLastY, t + kSegmentWidth);

        if (e.hasNextSegment()) {
            e.nextSegment();
            t += kSegmentWidth;
        }
    }
}

DEF_TEST(SkEdge_MostlyFlatQuad_SkipsZeroHeightSegments, r) {
    SkQuadraticEdge e;
    const SkPoint points[3] = {{4.f, 19.f}, {5.5f, 18.2f}, {10.f, 18.f}};

    REPORTER_ASSERT(r, e.setQuadratic(points));
    REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCCW);

    REPORTER_ASSERT(r, e.fFirstY == 18);
    REPORTER_ASSERT(r, e.fLastY == 18);

    // The x coordinate should be somewhere between B_x(0.25) and B_x(0.75). The exact value is
    // subject to the implementation's choice of dealing with segments that cover 0 height.
    SkQuadCoeff exact = SkQuadCoeff(points);
    const float kOneQuarterT = exact.eval({0.25f})[0];    // about 4.9375
    const float kThreeQuarterT = exact.eval({0.75f})[0];  // about 7.9375
    REPORTER_ASSERT(r,
                    e.fX > SkFloatToFixed(kOneQuarterT) && e.fX < SkFloatToFixed(kThreeQuarterT));

    // The slope should be negative, but precisely how much again depends the implementation.
    // The exact value doesn't matter much for this segment because it's 1) the last segment
    // and 2) only of height 1.
    REPORTER_ASSERT(r, e.fDxDy < 0);

    // This edge has covered the entire scanline, so there shouldn't be any more segments
    REPORTER_ASSERT(r, !e.hasNextSegment());
}

DEF_TEST(SkEdge_HorizontalishQuad_ReturnsFalse, r) {
    SkQuadraticEdge e;
    const SkPoint points[3] = {{4.f, 18.f}, {5.5f, 18.2f}, {10.f, 18.4f}};

    REPORTER_ASSERT(r, !e.setQuadratic(points));
}

DEF_TEST(SkEdge_Cubic_ApproximatedWithMultipleLineSegments, r) {
    SkCubicEdge e;
    const SkPoint points[4] = {{0.f, 0.f}, {2.f, 13.f}, {8.f, 6.f}, {10.f, 20.f}};

    REPORTER_ASSERT(r, e.setCubic(points));

    const SkCubicCoeff exact = SkCubicCoeff(points);
    auto assert_x_on_curve_between = [&](SkFixed x, float tLower, float tUpper) {
        const float lower = eval_x_at(exact, tLower);
        const float upper = eval_x_at(exact, tUpper);
        REPORTER_ASSERT(r, SkFixedToFloat(x) >= lower && SkFixedToFloat(x) < upper,
                        "%g was not in [%g, %g]",
                        SkFixedToFloat(x), lower, upper);
    };
    auto assert_y_starts_at = [&](int32_t y, float atT) {
        const float start = sk_float_round2int(eval_y_at(exact, atT));
        REPORTER_ASSERT(r, y == start, "%d was not %g", y, start);
    };
    auto assert_y_ends_at = [&](int32_t y, float atT) {
        const float end = sk_float_round2int(eval_y_at(exact, atT)) - 1;  // this range is exclusive
        REPORTER_ASSERT(r, y == end, "%d was not %g", y, end);
    };

    // SkCubicEdge will approximate a cubic Bezier curve with N line segments.
    // There are some heuristics to determine how many segments to use. For this curve, there are
    // 8 total segments - the current segment followed by 7 more.
    const int kNumSegments = 8;
    const float kSegmentWidth = 1.0f / kNumSegments;
    float t = 0.0f;
    for (int segments = kNumSegments - 1; segments >= 0; segments--) {
        skiatest::ReporterContext ctx(r,
                                      SkStringPrintf("Segment %d, t is [%g, %g]",
                                                     kNumSegments - segments - 1,
                                                     t,
                                                     t + kSegmentWidth));
        REPORTER_ASSERT(r, e.fWinding == SkEdge::Winding::kCW);
        REPORTER_ASSERT(r, e.segmentsLeft() == segments);

        // The slope for a line segment should be close to the curve at the midpoint between this
        // section of curve. e.g. for the segment [0.0, 0.25], it should be the slope at t=0.125
        const float segment1Slope = cubic_slope_at(points, kSegmentWidth / 2 + t);
        assert_within_n_percent(r, SkFixedToFloat(e.fDxDy), segment1Slope, 3);

        // The x value could vary a bit depending on implementation and rounding
        assert_x_on_curve_between(e.fX, t, t + kSegmentWidth);

        // The start and stopping y values should match the actual curve.
        assert_y_starts_at(e.fFirstY, t);
        assert_y_ends_at(e.fLastY, t + kSegmentWidth);

        if (e.hasNextSegment()) {
            e.nextSegment();
            t += kSegmentWidth;
        }
    }
}

DEF_TEST(SkBasicEdgeBuilder_TrapezoidNoClip_HasTwoEdges, r) {
    SkPathBuilder pb;
    SkPath path = pb.moveTo(5, 0)
                    .lineTo(0, 20)
                    .lineTo(20, 20)
                    .lineTo(10, 0)
                    .close()
                    .detach();

    SkBasicEdgeBuilder eb;
    int numEdges = eb.buildEdges(path, nullptr);
    REPORTER_ASSERT(r, numEdges == 2);

    SkEdge** edges = eb.edgeList();
    SkEdge* left = edges[0];
    SkEdge* right = edges[1];

    if (left->fX > right->fX) { // An implementation could return these edges in either order
        std::swap(left, right);
    }

    // left edge should go from (5,0) -> (0,20) (clockwise) which is a X/Y slope of -5/20
    REPORTER_ASSERT(r, left->fWinding == SkEdge::Winding::kCW);
    const float kLeftSlope = -0.25f;
    REPORTER_ASSERT(r, left->fDxDy == SkFloatToFixed(kLeftSlope));
    // fX will be slightly less than 5 because it's evaluated at y=0.5
    const float kLeftX = 5.f + kLeftSlope * 0.5f; // 4.875
    REPORTER_ASSERT(r, left->fX == SkFloatToFixed(kLeftX));
    REPORTER_ASSERT(r, left->fFirstY == 0);
    REPORTER_ASSERT(r, left->fLastY == 19); // this represents 19.5 and is inclusive

    // right edge should go from (20,20) -> (10,0) (counter clockwise) which is a X/Y slope of 10/20
    REPORTER_ASSERT(r, right->fWinding == SkEdge::Winding::kCCW);
    const float kRightSlope = 0.5f;
    REPORTER_ASSERT(r, right->fDxDy == SkFloatToFixed(kRightSlope));
    // fX will be slightly more than 10 because it's evaluated at y=0.5
    const float kRightX = 10.f + kRightSlope * 0.5f; // 10.25
    REPORTER_ASSERT(r, right->fX == SkFloatToFixed(kRightX));
    REPORTER_ASSERT(r, right->fFirstY == 0);
    REPORTER_ASSERT(r, right->fLastY == 19); // this represents 19.5 and is inclusive

    // Lines are "approximated" in one shot and have no need for follow-up approximations.
    REPORTER_ASSERT(r, !left->hasNextSegment());
    REPORTER_ASSERT(r, !right->hasNextSegment());
}
