/*
 * 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
}

static struct {
    const char* fStr;
    const SkRect fBounds;
} gRec[] = {
    { "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 } },
    { "", { 0, 0, 0, 0 } },
    { "M0,0L10,10", { 0, 0, SkIntToScalar(10), SkIntToScalar(10) } },
    { "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 {
        const char* fStr;
        int         fVerbs;
        int         fPoints;
    } gTests[] = {
        { "", 0, 0 },

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

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

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

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