/*
 * 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/SkPathTypes.h"
#include "src/core/SkPathData.h"
#include "src/core/SkPathPriv.h"

#include "tests/Test.h"

#include <functional>
#include <limits>

namespace {
template <typename T> bool spaneq(SkSpan<T> a, SkSpan<T> b) {
    if (a.size() != b.size()) {
        return false;
    }
    for (size_t i = 0; i < a.size(); ++i) {
        if (a[i] != b[i]) {
            return false;
        }
    }
    return true;
}
}

DEF_TEST(pathdata_empty, reporter) {
    auto pdata = SkPathData::Empty();

    REPORTER_ASSERT(reporter, pdata->empty());
    REPORTER_ASSERT(reporter, pdata->points().empty());
    REPORTER_ASSERT(reporter, pdata->conics().empty());
    REPORTER_ASSERT(reporter, pdata->verbs().empty());

    REPORTER_ASSERT(reporter, pdata->bounds() == SkRect::MakeEmpty());
    REPORTER_ASSERT(reporter, pdata->segmentMask() == 0);

    REPORTER_ASSERT(reporter, !pdata->asLine());
    REPORTER_ASSERT(reporter, !pdata->asOval());
    REPORTER_ASSERT(reporter, !pdata->asRect());
    REPORTER_ASSERT(reporter, !pdata->asRRect());

    auto xformed = pdata->makeTransform(SkMatrix::Scale(2, 3));
    REPORTER_ASSERT(reporter, *pdata == *xformed);
}

using IsAPredicate = bool(const SkPathData&);

static void check_asA_transforms(skiatest::Reporter* reporter, sk_sp<SkPathData> orig,
                                 IsAPredicate returns_asA) {
    SkASSERT(returns_asA(*orig));

    const struct {
        SkMatrix mx;
        bool     expectedAsA;
    } gPairs[] = {
        { SkMatrix::I(),             true },
        { SkMatrix::Translate(1, 2), true },
        { SkMatrix::Scale(2, 3),     true },
        { SkMatrix::RotateDeg(30),  false },
    };

    for (const auto& pair : gPairs) {
        auto pdata = orig->makeTransform(pair.mx);
        REPORTER_ASSERT(reporter, returns_asA(*pdata) == pair.expectedAsA);
    }
}

/*
 *  Differe ways to "make" a rectangular PathData
 */
using RectMaker = sk_sp<SkPathData>(const SkRect&, SkPathDirection);

static sk_sp<SkPathData> factory_rect(const SkRect& r, SkPathDirection d) {
    return SkPathData::Rect(r, d);
}
static sk_sp<SkPathData> poly4_rect(const SkRect& r, SkPathDirection d) {
    std::array<SkPoint, 4> pts = r.toQuad(d);
    return SkPathData::Polygon(pts, true);
}
static sk_sp<SkPathData> poly5_rect(const SkRect& r, SkPathDirection d) {
    std::array<SkPoint, 5> pts;
    r.copyToQuad(pts, d);
    pts[4] = pts[0];    // explicly add the closing line
    return SkPathData::Polygon(pts, true);
}
static sk_sp<SkPathData> builder_rect_rect(const SkRect& r, SkPathDirection d) {
    SkPathBuilder bu;
    bu.addRect(r, d);
    return bu.detachData();
}
static sk_sp<SkPathData> builder_poly4_rect(const SkRect& r, SkPathDirection d) {
    std::array<SkPoint, 4> pts = r.toQuad(d);
    SkPathBuilder bu;
    bu.addPolygon(pts, true);
    return bu.detachData();
}
static sk_sp<SkPathData> builder_poly5_rect(const SkRect& r, SkPathDirection d) {
    std::array<SkPoint, 5> pts;
    r.copyToQuad(pts, d);
    pts[4] = pts[0];    // explicly add the closing line
    SkPathBuilder bu;
    bu.addPolygon(pts, true);
    return bu.detachData();
}

RectMaker* const gRectMakers[] = {
    factory_rect,
    poly4_rect,
    poly5_rect,
    builder_rect_rect,
    builder_poly4_rect,
    builder_poly5_rect,
};

DEF_TEST(pathdata_rect, reporter) {
    const SkRect r = {1, 2, 3, 4};

    auto sign = [](float x) -> float {
        if (x == 0) {
            return 0;
        } else {
            return x > 0 ? 1 : -1;
        }
    };

    for (auto maker : gRectMakers) {
        for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
            auto pdata = maker(r, dir);
            REPORTER_ASSERT(reporter, r == pdata->bounds());

            // 1. manually determine if *we* think it is a rect

            const SkSpan<const SkPoint> pts = pdata->points();
            REPORTER_ASSERT(reporter, r == SkRect::Bounds(pts).value());

            const float crossSign = (dir == SkPathDirection::kCW) ? 1 : -1;
            for (int i = 1; i < 3; ++i) {
                SkVector u = pts[i]   - pts[i-1],
                         v = pts[i+1] - pts[i];
                const float cross = u.cross(v),
                            dot   = u.dot(v);
                REPORTER_ASSERT(reporter, dot == 0);
                REPORTER_ASSERT(reporter, crossSign == sign(cross));
            }

            // 2. now ask the pathdata

            auto isa = pdata->asRect();
            REPORTER_ASSERT(reporter, isa.has_value());
            REPORTER_ASSERT(reporter, isa->fRect == r);
            REPORTER_ASSERT(reporter, isa->fDirection == dir);
            REPORTER_ASSERT(reporter, isa->fStartIndex == 0);

            check_asA_transforms(reporter, pdata, [](const SkPathData& pd) {
                return pd.asRect().has_value();
            });
        }
    }
}

static sk_sp<SkPathData> factory_poly(SkSpan<const SkPoint> pts, bool isClosed) {
    return SkPathData::Polygon(pts, isClosed);
}
static sk_sp<SkPathData> builder_poly(SkSpan<const SkPoint> pts, bool isClosed) {
    SkPathBuilder bu;
    bu.addPolygon(pts, isClosed);
    return bu.detachData();
}

DEF_TEST(pathdata_polygon, reporter) {
    const SkPoint points[] = {
        {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9},
    };

    for (auto maker : {factory_poly, builder_poly}) {
        for (auto isClosed : {false, true}) {
            for (size_t n = 0; n <= std::size(points); ++n) {
                const SkSpan<const SkPoint> pts = {points, n};
                auto pdata = maker(pts, isClosed);

                const bool shouldBeEmpty = isClosed ? n == 0 : n <= 1;
                if (shouldBeEmpty) {
                    REPORTER_ASSERT(reporter, pdata->empty());
                    continue;
                }

                REPORTER_ASSERT(reporter, spaneq(pdata->points(), pts));
                REPORTER_ASSERT(reporter, pdata->conics().empty());

                auto line = pdata->asLine();
                if (n == 2 && !isClosed) {
                    REPORTER_ASSERT(reporter, line.has_value());
                    REPORTER_ASSERT(reporter, line.value()[0] == points[0]);
                    REPORTER_ASSERT(reporter, line.value()[1] == points[1]);

                    auto pline = SkPathData::Line(points[0], points[1]);
                    REPORTER_ASSERT(reporter, *pline == *pdata);
                } else {
                    REPORTER_ASSERT(reporter, !line.has_value());
                }

                const size_t expectedVerbs = pts.size() + isClosed;
                auto vbs = pdata->verbs();
                REPORTER_ASSERT(reporter, vbs.size() == expectedVerbs);

                REPORTER_ASSERT(reporter, vbs[0] == SkPathVerb::kMove);
                for (size_t i = 1; i < pts.size(); ++i) {
                    REPORTER_ASSERT(reporter, vbs[i] == SkPathVerb::kLine);
                }
                if (isClosed) {
                    REPORTER_ASSERT(reporter, vbs.back() == SkPathVerb::kClose);
                }
            }
        }
    }
}

static sk_sp<SkPathData> factory_oval(const SkRect& r, SkPathDirection dir, unsigned start) {
    return SkPathData::Oval(r, dir, start);
}
static sk_sp<SkPathData> builder_oval(const SkRect& r, SkPathDirection dir, unsigned start) {
    SkPathBuilder bu;
    bu.addOval(r, dir, start);
    return bu.detachData();
}

DEF_TEST(pathdata_oval, reporter) {
    const SkRect bounds = {1, 2, 3, 4};
    const unsigned kStartIndexCount = 4;

    for (auto maker : {factory_oval, builder_oval}) {
        for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
            for (unsigned start = 0; start < kStartIndexCount; ++start) {
                auto pdata = maker(bounds, dir, start);

                REPORTER_ASSERT(reporter, pdata->bounds() == bounds);

                auto oval = pdata->asOval();
                REPORTER_ASSERT(reporter, oval.has_value());
                REPORTER_ASSERT(reporter, oval->fBounds == bounds);
                REPORTER_ASSERT(reporter, oval->fDirection == dir);
                REPORTER_ASSERT(reporter, oval->fStartIndex == start);

                check_asA_transforms(reporter, pdata, [](const SkPathData& pd) {
                    return pd.asOval().has_value();
                });
            }
        }
    }
}

static sk_sp<SkPathData> factory_rrect(const SkRRect& r, SkPathDirection dir, unsigned start) {
    return SkPathData::RRect(r, dir, start);
}
static sk_sp<SkPathData> builder_rrect(const SkRRect& r, SkPathDirection dir, unsigned start) {
    SkPathBuilder bu;
    bu.addRRect(r, dir, start);
    return bu.detachData();
}

DEF_TEST(pathdata_rrect, reporter) {
    const SkRect bounds = {0, 0, 20, 30};
    const SkRRect rrect = SkRRect::MakeRectXY(bounds, 2, 3);
    const unsigned kStartIndexCount = 8;

    for (auto maker : {factory_rrect, builder_rrect}) {
        for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
            for (unsigned start = 0; start < kStartIndexCount; ++start) {
                auto pdata = maker(rrect, dir, start);

                REPORTER_ASSERT(reporter, pdata->bounds() == bounds);

                auto rr = pdata->asRRect();
                REPORTER_ASSERT(reporter, rr.has_value());
                REPORTER_ASSERT(reporter, rr->fRRect == rrect);
                REPORTER_ASSERT(reporter, rr->fDirection == dir);
                REPORTER_ASSERT(reporter, rr->fStartIndex == start);

                check_asA_transforms(reporter, pdata, [](const SkPathData& pd) {
                    return pd.asRRect().has_value();
                });
            }
        }
    }
}

DEF_TEST(pathdata_make_edgecases, reporter) {

    // just create some points for our tests
    SkPoint pts[20];
    for (size_t i = 0; i < std::size(pts); ++i) {
        pts[i] = {i * 1.0f, i * 1.0f };
    }
    const float conicWeights[] = {1.5f, 2, 3};

    constexpr SkPathVerb M = SkPathVerb::kMove,
                         L = SkPathVerb::kLine,
                         Q = SkPathVerb::kQuad,
                         K = SkPathVerb::kConic,
                         C = SkPathVerb::kCubic,
                         X = SkPathVerb::kClose;

    // only these two sequence will result in an "empty" PathData

    const SkPathVerb move[] = { M };  // the M will not be trimmed

    REPORTER_ASSERT(reporter, SkPathData::Make({}, {}, {})->empty());
    REPORTER_ASSERT(reporter, !SkPathData::Make({pts, 1}, move, {})->empty());

    // these sequenes are all illegal (bad verb sequencing)

    const SkPathVerb bad0[] = { L };            // didn't start with M
    const SkPathVerb bad1[] = { M, M, L };      // consecutive Ms
    const SkPathVerb bad2[] = { M, L, X, X};    // consecutive Xs
    const SkPathVerb bad3[] = { M, L, M, M};    // consecutive Ms

    REPORTER_ASSERT(reporter, SkPathData::Make({pts, 1}, bad0, {}) == nullptr);
    REPORTER_ASSERT(reporter, SkPathData::Make({pts, 3}, bad1, {}) == nullptr);
    REPORTER_ASSERT(reporter, SkPathData::Make({pts, 2}, bad2, {}) == nullptr);
    REPORTER_ASSERT(reporter, SkPathData::Make({pts, 4}, bad3, {}) == nullptr);

    // Odd but legal, the trailing M is preserved, but not part of the bounds

    const SkPathVerb trimmed[] = { M, L, M }; //legal
    auto pdata = SkPathData::Make({pts, 3}, trimmed, {});

    REPORTER_ASSERT(reporter, pdata->points().size() == 3);
    REPORTER_ASSERT(reporter, pdata->verbs().size() == 3);
    REPORTER_ASSERT(reporter, pdata->bounds() == SkRect::Bounds({pts, 2}).value());

    // Now check on # of points and conic weights

    const SkPathVerb verbs[] = { M, L, Q, K, C, X, M };    // 1+1+2+2+3+0+1 = 10 + 1 conic weight

    const struct {
        size_t nPts, nConics;
        bool success;
    } combos[] = {
        { 10, 1, true  },   // just right
        {  9, 1, false },   // not enough points
        { 11, 1, false },   // too many points
        { 10, 0, false },   // not enough conics
        { 10, 2, false },   // too many conics
        {  0, 1, false },   // degenerate, should not crash on moveto trim
    };
    for (auto c : combos) {
        pdata = SkPathData::Make({pts, c.nPts}, verbs, {conicWeights, c.nConics});
        if (c.success) {
            REPORTER_ASSERT(reporter, pdata != nullptr);
        } else {
            REPORTER_ASSERT(reporter, pdata == nullptr);
        }
    }
}

static inline std::optional<SkRRect> make_bad_rrect() {
    constexpr float big = std::numeric_limits<float>::max();
    SkRRect rr = SkRRect::MakeRectXY({0, 0, big, big}, 4, 4);
    rr.offset(big, big);
    if (!rr.rect().isFinite()) {
        return rr;
    }
    return {};  // failed to make a non-finite rrect
}

/*
 *  Test that we cannot make a non-finite PathData
 */
DEF_TEST(pathdata_make_nonfinite, reporter) {
    const float inf = SK_FloatInfinity;

    SkPoint pts[] = {
        {0, 0}, {inf, 1}, {2, 4},
    };
    SkPathVerb vbs[] = {
        SkPathVerb::kMove, SkPathVerb::kConic,
    };
    float weights[] = { 2 };

    sk_sp<SkPathData> pdata = SkPathData::Make(pts, vbs, weights);
    REPORTER_ASSERT(reporter, pdata == nullptr);

    pts[1].fX = 3;  // remove non-finite from pts
    const float badWValues[] = { -1, inf, -inf, inf * 0 /* nan */ };
    for (auto bad : badWValues) {
        weights[0] = bad;
        REPORTER_ASSERT(reporter, SkPathData::Make(pts, vbs, weights) == nullptr);
    }

    SkRect r = {1, 2, inf, 4};
    REPORTER_ASSERT(reporter, SkPathData::Rect(r) == nullptr);
    REPORTER_ASSERT(reporter, SkPathData::Oval(r) == nullptr);

    // Most RRect methods 'sanitize' the values before returning the RRect, so it hard to
    // actually make one for testing. If our attempt suceeds, we will test with it.
    if (auto rr = make_bad_rrect()) {
        REPORTER_ASSERT(reporter, SkPathData::RRect(*rr) == nullptr);
    }

    pts[1].fX = inf;  // restore non-finite value
    REPORTER_ASSERT(reporter, SkPathData::Polygon(pts, false) == nullptr);

    {
        // Non-finite trailing moves should also be rejected.
        SkPathVerb v[] = { SkPathVerb::kMove, SkPathVerb::kLine, SkPathVerb::kMove };
        SkPoint    p[] = { {0, 0}, {10, 10}, {inf, 20} };
        REPORTER_ASSERT(reporter, SkPathData::Make(p, v) == nullptr);
    }
}

DEF_TEST(pathdata_transform, reporter) {
    SkMatrix mx;
    const SkRect r = {10, 20, 30, 40};
    auto data = SkPathData::Oval(r);

    mx = SkMatrix::I();
    auto newd = data->makeTransform(mx);
    REPORTER_ASSERT(reporter, *newd == *data);

    mx = SkMatrix::Translate(5, 6);
    newd = data->makeTransform(mx);
    REPORTER_ASSERT(reporter, newd->bounds() == r.makeOffset(5, 6));

    mx = SkMatrix::Scale(0.5f, 2);
    newd = data->makeTransform(mx);
    SkRect r2 = {
        r.fLeft * 0.5f,
        r.fTop * 2,
        r.fRight * 0.5f,
        r.fBottom * 2,
    };
    REPORTER_ASSERT(reporter, newd->bounds() == r2);

    mx = SkMatrix::Scale(SK_FloatInfinity, 2);
    newd = data->makeTransform(mx);
    REPORTER_ASSERT(reporter, newd == nullptr);

    mx = SkMatrix::Scale(SK_ScalarNaN, 2);
    newd = data->makeTransform(mx);
    REPORTER_ASSERT(reporter, newd == nullptr);
}

/*
 *  This tests how convexity is tracked under transformation
 *  1. unknown stays unknown (we don't actively compute convexity)
 *  2. concave stays concave
 *  3. convex ... may stay convex -- it depends if we feel it is (numerically) safe.
 *     See SkPathPriv::TransformConvexity() for the current heuristics.
 *  4. The (above) helper is shared with SkPath::transform(), so it and SkPathData
 *     should handle transforms + convexity the same.
 */
DEF_TEST(pathdata_transform_convexity, reporter) {
    const SkPoint pts[] = {
        {0, 0}, {100, 0}, {200, 0}, {200, 200},
    };
    // needed late for our assumpts about convexity preservation
    REPORTER_ASSERT(reporter, SkPathPriv::IsAxisAligned(pts));

    auto src = SkPathData::Polygon(pts, true);
    auto convexity = SkPathPriv::GetConvexityOrUnknown(*src);

    // don't do any work we didn't ask for
    REPORTER_ASSERT(reporter, convexity == SkPathConvexity::kUnknown);
    auto raw = src->raw(SkPathFillType::kDefault, SkResolveConvexity::kNo);
    REPORTER_ASSERT(reporter, raw.fConvexity == SkPathConvexity::kUnknown);
    // now ask for it
    raw = src->raw(SkPathFillType::kDefault, SkResolveConvexity::kYes);
    REPORTER_ASSERT(reporter, raw.isKnownToBeConvex());

    // For these matrices, given that our points are axis-aligned, we should be able
    // to preserve whatever convexity our src has.

    const SkMatrix safeMatrices[] = {
        SkMatrix(), SkMatrix::Translate(1, 2), SkMatrix::Scale(2, 3),
    };
    const SkPathConvexity convexities[] = {
        SkPathConvexity::kUnknown,
        SkPathConvexity::kConvex_CW,    // matches our test data
        SkPathConvexity::kConcave,
    };
    for (const auto& mx : safeMatrices) {
        for (auto conv : convexities) {
            raw.fConvexity = conv;
            auto dst = SkPathData::MakeTransform(raw, mx);
            convexity = SkPathPriv::GetConvexityOrUnknown(*dst);
            REPORTER_ASSERT(reporter, convexity == conv);
        }
    }

    // for this matrix, we do not expect to preserve convexity
    // (since we don't choose to actually compute convexity at this stage)
    SkMatrix mx = SkMatrix::RotateDeg(30);
    for (auto conv : convexities) {
        raw.fConvexity = conv;
        auto dst = SkPathData::MakeTransform(raw, mx);
        convexity = SkPathPriv::GetConvexityOrUnknown(*dst);
        auto expected = SkPathConvexity_IsConvex(conv) ? SkPathConvexity::kUnknown
                                                       : conv;
        REPORTER_ASSERT(reporter, convexity == expected);
    }
}

DEF_TEST(pathdata_inverted_bounds, reporter) {
    using makerT = std::function<sk_sp<SkPathData>(const SkRect&)>;
    const auto check = [&reporter](const makerT& maker) {
        constexpr SkRect bounds = {-10, -10, 10, 10};
        constexpr SkRect inverted_bounds = {10, 10, -10, -10};
        REPORTER_ASSERT(reporter, maker(bounds)->bounds() == bounds);
        REPORTER_ASSERT(reporter, maker(inverted_bounds)->bounds() == bounds);
    };

    {
        for (auto maker : {factory_rect, builder_rect_rect}) {
            for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
                check([&maker, dir](const SkRect& r) { return maker(r, dir); });
            }
        }
    }

    {
        constexpr unsigned kStartIndexCount = 4;
        for (auto maker : {factory_oval, builder_oval}) {
            for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
                for (unsigned start = 0; start < kStartIndexCount; ++start) {
                    check([&maker, dir, start](const SkRect& r) { return maker(r, dir, start); });
                }
            }
        }
    }

    {
        constexpr unsigned kStartIndexCount = 8;
        for (auto maker : {factory_rrect, builder_rrect}) {
            for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
                for (unsigned start = 0; start < kStartIndexCount; ++start) {
                    for (int sign : {1, -1}) {
                        check([&maker, dir, start, sign](const SkRect& r) {
                            const SkRRect rrect = SkRRect::MakeRectXY(r, sign * 2, sign * 3);
                            return maker(rrect, dir, start);
                        });
                    }
                }
            }
        }
    }
}
