/*
 * Copyright 2025 Google Inc.
 *
 * 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 "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 empty[] = { M };  // the M will be trimmed

    REPORTER_ASSERT(reporter, SkPathData::Make({}, {empty, 0}, {})->empty());
    REPORTER_ASSERT(reporter, SkPathData::Make({pts, 1}, empty, {})->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 will be removed

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

    REPORTER_ASSERT(reporter, pdata->points().size() == 2);
    REPORTER_ASSERT(reporter, pdata->verbs().size() == 2);

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

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