/*
 * Copyright 2022 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/SkFontMgr.h"
#include "modules/skottie/src/text/SkottieShaper.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"

using namespace skottie;

DEF_TEST(Skottie_Shaper_Clusters, r) {
    const SkString text("Foo \rbar \rBaz.");

    auto check_clusters = [](skiatest::Reporter* r, const SkString& text, Shaper::Flags flags,
                             const std::vector<size_t>& expected_clusters) {
        const Shaper::TextDesc desc = {
            ToolUtils::create_portable_typeface("Serif", SkFontStyle()),
            18,
            0, 18,
            18,
             0,
             0,
            SkTextUtils::Align::kCenter_Align,
            Shaper::VAlign::kTop,
            Shaper::ResizePolicy::kNone,
            Shaper::LinebreakPolicy::kParagraph,
            Shaper::Direction::kLTR,
            Shaper::Capitalization::kNone,
            0,
            flags
        };
        const auto result = Shaper::Shape(text, desc, SkRect::MakeWH(1000, 1000),
                                          SkFontMgr::RefDefault());
        REPORTER_ASSERT(r, !result.fFragments.empty());

        size_t i = 0;
        for (const auto& frag : result.fFragments) {
            const auto& glyphs = frag.fGlyphs;

            if (flags & Shaper::kClusters) {
                REPORTER_ASSERT(r, glyphs.fClusters.size() == glyphs.fGlyphIDs.size());
            }

            for (const auto& utf_cluster : glyphs.fClusters) {
                REPORTER_ASSERT(r, i < expected_clusters.size());
                REPORTER_ASSERT(r, utf_cluster == expected_clusters[i++]);
            }
        }

        REPORTER_ASSERT(r, i == expected_clusters.size());
    };

    check_clusters(r, text, Shaper::kNone, {});
    check_clusters(r, text, Shaper::kFragmentGlyphs, {});
    check_clusters(r, text, Shaper::kClusters,
                   {0, 1, 2, 3,    5, 6, 7, 8,    10, 11, 12, 13});
    check_clusters(r, text, (Shaper::Flags)(Shaper::kClusters | Shaper::kFragmentGlyphs),
                   {0, 1, 2, 3,    5, 6, 7, 8,    10, 11, 12, 13});
}

DEF_TEST(Skottie_Shaper_HAlign, reporter) {
    auto typeface = SkTypeface::MakeDefault();
    REPORTER_ASSERT(reporter, typeface);

    static constexpr struct {
        SkScalar text_size,
                 tolerance;
    } kTestSizes[] = {
        // These gross tolerances are required for the test to pass on NativeFonts bots.
        // Might be worth investigating why we need so much slack.
        {  5, 2.0f },
        { 10, 2.0f },
        { 15, 2.4f },
        { 25, 4.4f },
    };

    static constexpr struct {
        SkTextUtils::Align align;
        SkScalar           l_selector,
                           r_selector;
    } kTestAligns[] = {
        { SkTextUtils::  kLeft_Align, 0.0f, 1.0f },
        { SkTextUtils::kCenter_Align, 0.5f, 0.5f },
        { SkTextUtils:: kRight_Align, 1.0f, 0.0f },
    };

    const SkString text("Foo, bar.\rBaz.");
    const SkPoint  text_point = SkPoint::Make(100, 100);

    for (const auto& tsize : kTestSizes) {
        for (const auto& talign : kTestAligns) {
            const skottie::Shaper::TextDesc desc = {
                typeface,
                tsize.text_size,
                0, tsize.text_size,
                tsize.text_size,
                0,
                0,
                talign.align,
                Shaper::VAlign::kTopBaseline,
                Shaper::ResizePolicy::kNone,
                Shaper::LinebreakPolicy::kExplicit,
                Shaper::Direction::kLTR,
                Shaper::Capitalization::kNone,
            };

            const auto shape_result = Shaper::Shape(text, desc, text_point,
                                                    SkFontMgr::RefDefault());
            REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
            REPORTER_ASSERT(reporter, !shape_result.fFragments[0].fGlyphs.fRuns.empty());

            const auto shape_bounds = shape_result.computeVisualBounds();
            REPORTER_ASSERT(reporter, !shape_bounds.isEmpty());

            const auto expected_l = text_point.x() - shape_bounds.width() * talign.l_selector;
            REPORTER_ASSERT(reporter,
                            std::fabs(shape_bounds.left() - expected_l) < tsize.tolerance,
                            "%f %f %f %f %d", shape_bounds.left(), expected_l, tsize.tolerance,
                                              tsize.text_size, talign.align);

            const auto expected_r = text_point.x() + shape_bounds.width() * talign.r_selector;
            REPORTER_ASSERT(reporter,
                            std::fabs(shape_bounds.right() - expected_r) < tsize.tolerance,
                            "%f %f %f %f %d", shape_bounds.right(), expected_r, tsize.tolerance,
                                              tsize.text_size, talign.align);

        }
    }
}

DEF_TEST(Skottie_Shaper_VAlign, reporter) {
    auto typeface = SkTypeface::MakeDefault();
    REPORTER_ASSERT(reporter, typeface);

    static constexpr struct {
        SkScalar text_size,
                 tolerance;
    } kTestSizes[] = {
        // These gross tolerances are required for the test to pass on NativeFonts bots.
        // Might be worth investigating why we need so much slack.
        {  5, 2.0f },
        { 10, 4.0f },
        { 15, 5.5f },
        { 25, 8.0f },
    };

    struct {
        skottie::Shaper::VAlign align;
        SkScalar                topFactor;
    } kTestAligns[] = {
        { skottie::Shaper::VAlign::kVisualTop   , 0.0f },
        { skottie::Shaper::VAlign::kVisualCenter, 0.5f },
        // TODO: any way to test kTopBaseline?
    };

    const SkString text("Foo, bar.\rBaz.");
    const auto text_box = SkRect::MakeXYWH(100, 100, 1000, 1000); // large-enough to avoid breaks.


    for (const auto& tsize : kTestSizes) {
        for (const auto& talign : kTestAligns) {
            const skottie::Shaper::TextDesc desc = {
                typeface,
                tsize.text_size,
                0, tsize.text_size,
                tsize.text_size,
                0,
                0,
                SkTextUtils::Align::kCenter_Align,
                talign.align,
                Shaper::ResizePolicy::kNone,
                Shaper::LinebreakPolicy::kParagraph,
                Shaper::Direction::kLTR,
                Shaper::Capitalization::kNone,
            };

            const auto shape_result = Shaper::Shape(text, desc, text_box, SkFontMgr::RefDefault());
            REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
            REPORTER_ASSERT(reporter, !shape_result.fFragments[0].fGlyphs.fRuns.empty());

            const auto shape_bounds = shape_result.computeVisualBounds();
            REPORTER_ASSERT(reporter, !shape_bounds.isEmpty());

            const auto v_diff = text_box.height() - shape_bounds.height();

            const auto expected_t = text_box.top() + v_diff * talign.topFactor;
            REPORTER_ASSERT(reporter,
                            std::fabs(shape_bounds.top() - expected_t) < tsize.tolerance,
                            "%f %f %f %f %d", shape_bounds.top(), expected_t, tsize.tolerance,
                                              tsize.text_size, SkToU32(talign.align));

            const auto expected_b = text_box.bottom() - v_diff * (1 - talign.topFactor);
            REPORTER_ASSERT(reporter,
                            std::fabs(shape_bounds.bottom() - expected_b) < tsize.tolerance,
                            "%f %f %f %f %d", shape_bounds.bottom(), expected_b, tsize.tolerance,
                                              tsize.text_size, SkToU32(talign.align));
        }
    }
}

DEF_TEST(Skottie_Shaper_FragmentGlyphs, reporter) {
    skottie::Shaper::TextDesc desc = {
        SkTypeface::MakeDefault(),
        18,
        0, 18,
        18,
         0,
         0,
        SkTextUtils::Align::kCenter_Align,
        Shaper::VAlign::kTop,
        Shaper::ResizePolicy::kNone,
        Shaper::LinebreakPolicy::kParagraph,
        Shaper::Direction::kLTR,
        Shaper::Capitalization::kNone,
    };

    const SkString text("Foo bar baz");
    const auto text_box = SkRect::MakeWH(100, 100);

    {
        const auto shape_result = Shaper::Shape(text, desc, text_box, SkFontMgr::RefDefault());
        // Default/consolidated mode => single blob result.
        REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
        REPORTER_ASSERT(reporter, !shape_result.fFragments[0].fGlyphs.fRuns.empty());
    }

    {
        desc.fFlags = Shaper::Flags::kFragmentGlyphs;
        const auto shape_result = skottie::Shaper::Shape(text, desc, text_box,
                                                         SkFontMgr::RefDefault());
        // Fragmented mode => one blob per glyph.
        const size_t expectedSize = text.size();
        REPORTER_ASSERT(reporter, shape_result.fFragments.size() == expectedSize);
        for (size_t i = 0; i < expectedSize; ++i) {
            REPORTER_ASSERT(reporter, !shape_result.fFragments[i].fGlyphs.fRuns.empty());
        }
    }
}

#if defined(SK_SHAPER_HARFBUZZ_AVAILABLE) && !defined(SK_BUILD_FOR_WIN)

DEF_TEST(Skottie_Shaper_ExplicitFontMgr, reporter) {
    class CountingFontMgr : public SkFontMgr {
    public:
        size_t fallbackCount() const { return fFallbackCount; }

    protected:
        int onCountFamilies() const override { return 0; }
        void onGetFamilyName(int index, SkString* familyName) const override {
            SkDEBUGFAIL("onGetFamilyName called with bad index");
        }
        SkFontStyleSet* onCreateStyleSet(int index) const override {
            SkDEBUGFAIL("onCreateStyleSet called with bad index");
            return nullptr;
        }
        SkFontStyleSet* onMatchFamily(const char[]) const override {
            return SkFontStyleSet::CreateEmpty();
        }

        SkTypeface* onMatchFamilyStyle(const char[], const SkFontStyle&) const override {
            return nullptr;
        }
        SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
                                                const SkFontStyle& style,
                                                const char* bcp47[],
                                                int bcp47Count,
                                                SkUnichar character) const override {
            fFallbackCount++;
            return nullptr;
        }

        sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int) const override {
            return nullptr;
        }
        sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>, int) const override {
            return nullptr;
        }
        sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
                                               const SkFontArguments&) const override {
            return nullptr;
        }
        sk_sp<SkTypeface> onMakeFromFile(const char[], int) const override {
            return nullptr;
        }
        sk_sp<SkTypeface> onLegacyMakeTypeface(const char [], SkFontStyle) const override {
            return nullptr;
        }
    private:
        mutable size_t fFallbackCount = 0;
    };

    auto fontmgr = sk_make_sp<CountingFontMgr>();

    skottie::Shaper::TextDesc desc = {
        ToolUtils::create_portable_typeface(),
        18,
        0, 18,
        18,
         0,
         0,
        SkTextUtils::Align::kCenter_Align,
        Shaper::VAlign::kTop,
        Shaper::ResizePolicy::kNone,
        Shaper::LinebreakPolicy::kParagraph,
        Shaper::Direction::kLTR,
        Shaper::Capitalization::kNone,
    };

    const auto text_box = SkRect::MakeWH(100, 100);

    {
        const auto shape_result = Shaper::Shape(SkString("foo bar"), desc, text_box, fontmgr);

        REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
        REPORTER_ASSERT(reporter, !shape_result.fFragments[0].fGlyphs.fRuns.empty());
        REPORTER_ASSERT(reporter, fontmgr->fallbackCount() == 0ul);
        REPORTER_ASSERT(reporter, shape_result.fMissingGlyphCount == 0);
    }

    {
        // An unassigned codepoint should trigger fallback.
        const auto shape_result = skottie::Shaper::Shape(SkString("foo\U000DFFFFbar"),
                                                         desc, text_box, fontmgr);

        REPORTER_ASSERT(reporter, shape_result.fFragments.size() == 1ul);
        REPORTER_ASSERT(reporter, !shape_result.fFragments[0].fGlyphs.fRuns.empty());
        REPORTER_ASSERT(reporter, fontmgr->fallbackCount() == 1ul);
        REPORTER_ASSERT(reporter, shape_result.fMissingGlyphCount == 1ul);
    }
}

#endif

