/*
 * Copyright 2011 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/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/utils/SkParsePath.h"
#include "tests/Test.h"

#include <array>
#include <cstddef>

static void test_to_from(skiatest::Reporter* reporter, const SkPath& path) {
    SkString str = SkParsePath::ToSVGString(path);

    auto path2 = SkParsePath::FromSVGString(str.c_str());
    REPORTER_ASSERT(reporter, path2.has_value());

    SkString str2 = SkParsePath::ToSVGString(*path2);
    REPORTER_ASSERT(reporter, str == str2);
#if 0 // closed paths are not equal, the iter explicitly gives the closing
      // edge, even if it is not in the path.
    REPORTER_ASSERT(reporter, path == path2);
    if (path != path2) {
        SkDebugf("str1=%s\nstr2=%s\n", str.c_str(), str2.c_str());
    }
#endif
}

struct Rec {
    const char* fStr;
    const SkRect fBounds;
};
static constexpr auto gRec = std::to_array<Rec>({
        Rec{"M1,1 l-2.58-2.828-3.82-0.113, 1.9-3.3223-1.08-3.6702, 3.75,0.7744,3.16-2.1551,"
            "0.42,3.8008,3.02,2.3384-3.48,1.574-1.29,3.601z",
            {-5.39999962f, -10.3142f, 5.77000046f, 1.f}},
        Rec{"", {0, 0, 0, 0}},
        Rec{"M0,0L10,10", {0, 0, SkIntToScalar(10), SkIntToScalar(10)}},
        Rec{"M-5.5,-0.5 Q 0 0 6,6.50", {-5.5f, -0.5f, 6, 6.5f}},
});

DEF_TEST(ParsePath, reporter) {
    for (size_t i = 0; i < std::size(gRec); i++) {
        auto path = SkParsePath::FromSVGString(gRec[i].fStr);
        REPORTER_ASSERT(reporter, path.has_value());
        const SkRect& expectedBounds = gRec[i].fBounds;
        const SkRect& pathBounds = path->getBounds();
        REPORTER_ASSERT(reporter, expectedBounds == pathBounds);

        test_to_from(reporter, *path);
    }

    SkRect r;
    r.setLTRB(0, 0, 10, 10.5f);
    SkPathBuilder p;
    p.addRect(r);
    test_to_from(reporter, p.snapshot());
    p.addOval(r);
    test_to_from(reporter, p.snapshot());
    p.addRRect(SkRRect::MakeRectXY(r, 4, 4.5f));
    test_to_from(reporter, p.snapshot());
}

static void testInvalidPath(skiatest::Reporter* reporter, const std::string& name,
                            const std::string& input) {
    skiatest::ReporterContext subtest(reporter, name);
    auto path = SkParsePath::FromSVGString(input.c_str());
    REPORTER_ASSERT(reporter, !path.has_value());
}

DEF_TEST(ParsePath_InvalidDoesNotCrash, r) {
    testInvalidPath(r, "empty move", "M");
    testInvalidPath(r, "partial move", "M 5");
    testInvalidPath(r, "partial vertical line", "V"); // oss-fuzz:68723
    testInvalidPath(r, "partial horizontal line", "H");
    testInvalidPath(r, "partial cubic", "C 1 2");
    testInvalidPath(r, "partial continued cubic", "S 6 7");
    testInvalidPath(r, "partial quad", "Q 3 4 5");
    testInvalidPath(r, "partial continued quad", "T");
    testInvalidPath(r, "partial arc", "A 1 2 3 4 5 6");
    testInvalidPath(r, "partial ~", "~ 7 6 5");
}

DEF_TEST(ParsePathOptionalCommand, r) {
    struct Tests {
        const char* fStr;
        int         fVerbs;
        int         fPoints;
    };
    static constexpr auto gTests = std::to_array<Tests>({
            Tests{"", 0, 0},

            Tests{"H100 200 ", 3, 3},
            Tests{"H-100-200", 3, 3},
            Tests{"H+100+200", 3, 3},
            Tests{"H.10.20"  , 3, 3},
            Tests{"H-.10-.20", 3, 3},
            Tests{"H+.10+.20", 3, 3},

            Tests{"L100 100 200 200" , 3, 3},
            Tests{"L-100-100-200-200", 3, 3},
            Tests{"L+100+100+200+200", 3, 3},
            Tests{"L.10.10.20.20"    , 3, 3},
            Tests{"L-.10-.10-.20-.20", 3, 3},
            Tests{"L+.10+.10+.20+.20", 3, 3},

            Tests{"C100 100 200 200 300 300 400 400 500 500 600 600" , 3, 7},
            Tests{"C100-100-200-200-300-300-400-400-500-500-600-600" , 3, 7},
            Tests{"C100+100+200+200+300+300+400+400+500+500+600+600" , 3, 7},
            Tests{"C.10.10.20.20.30.30.40.40.50.50.60.60"            , 3, 7},
            Tests{"C-.10-.10-.20-.20-.30-.30-.40-.40-.50-.50-.60-.60", 3, 7},
            Tests{"C+.10+.10+.20+.20+.30+.30+.40+.40+.50+.50+.60+.60", 3, 7},

            Tests{"c-1.49.71-2.12 2.5-1.4 4 .71 1.49 2.5 2.12 4 1.4z", 4, 7},
    });

    for (size_t i = 0; i < std::size(gTests); ++i) {
        auto path = SkParsePath::FromSVGString(gTests[i].fStr);
        REPORTER_ASSERT(r, path.has_value());
        REPORTER_ASSERT(r, path->countVerbs() == gTests[i].fVerbs);
        REPORTER_ASSERT(r, path->countPoints() == gTests[i].fPoints);
    }
}

DEF_TEST(ParsePathArcFlags, r) {
    const char* arcs = "M10 10a2.143 2.143 0 100-4.285 2.143 2.143 0 000 4.286";
    auto path = SkParsePath::FromSVGString(arcs);
    REPORTER_ASSERT(r, path.has_value());
    // Arcs decompose to two conics.
    REPORTER_ASSERT(r, path->countVerbs() == 5);
    // One for move, 2x per conic.
    REPORTER_ASSERT(r, path->countPoints() == 9);
}
