/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <unordered_map>

#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkStream.h"
#include "modules/skottie/include/Skottie.h"
#include "modules/skottie/include/SkottieProperty.h"
#include "modules/skshaper/include/SkShaper_factory.h"
#include "modules/skshaper/utils/FactoryHelpers.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

using namespace skottie;

namespace {

class RecordMatchFamilyStyleSkFontMgr : public SkFontMgr {
public:
    const SkFontStyle* styleRequestedWhenMatchingFamily(const char* family) const {
        auto s = fStyleRequestedWhenMatchingFamily.find(family);
        return s != fStyleRequestedWhenMatchingFamily.end() ? &s->second : nullptr;
    }

private:
    int onCountFamilies() const override { return 0; }
    void onGetFamilyName(int index, SkString* familyName) const override {}
    sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override { return nullptr; }

    sk_sp<SkFontStyleSet> onMatchFamily(const char[]) const override { return nullptr; }

    sk_sp<SkTypeface> onMatchFamilyStyle(const char family[],
                                         const SkFontStyle& style) const override {
        fStyleRequestedWhenMatchingFamily[family] = style;
        return nullptr;
    }
    sk_sp<SkTypeface> onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style,
                                                  const char* bcp47[], int bcp47Count,
                                                  SkUnichar character) const override {
        fStyleRequestedWhenMatchingFamily[familyName] = style;
        return nullptr;
    }

    sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override {
        return nullptr;
    }
    sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
                                            int ttcIndex) const override {
        return nullptr;
    }
    sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
                                           const SkFontArguments&) const override {
        return nullptr;
    }
    sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
        return nullptr;
    }

    sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override {
        return nullptr;
    }

    mutable std::unordered_map<std::string, SkFontStyle> fStyleRequestedWhenMatchingFamily;
};

} // namespace

// This test relies on Skottie internals/implementation details, and may need to
// be updated in the future, if Skottie font resolution changes.
DEF_TEST(Skottie_Text_Style, r) {
    static constexpr char json[] =
        R"({
             "v": "5.2.1",
             "w": 100,
             "h": 100,
             "fr": 10,
             "ip": 0,
             "op": 100,
             "fonts": {
               "list": [
                 { "fName"  : "f1", "fFamily": "f1", "fStyle" : "Regular"   },
                 { "fName"  : "f2", "fFamily": "f2", "fStyle" : "Medium"    },
                 { "fName"  : "f3", "fFamily": "f3", "fStyle" : "Bold"      },
                 { "fName"  : "f4", "fFamily": "f4", "fStyle" : "Light"     },
                 { "fName"  : "f5", "fFamily": "f5", "fStyle" : "Extra"     },
                 { "fName"  : "f6", "fFamily": "f6", "fStyle" : "ExtraBold" },

                 { "fName"  : "f7" , "fFamily": "f7" , "fStyle" : "Regular Italic"    },
                 { "fName"  : "f8" , "fFamily": "f8" , "fStyle" : "Medium Italic"     },
                 { "fName"  : "f9" , "fFamily": "f9" , "fStyle" : "Bold Italic"       },
                 { "fName"  : "f10", "fFamily": "f10", "fStyle" : "Light Oblique"     },
                 { "fName"  : "f11", "fFamily": "f11", "fStyle" : "Extra Oblique"     },
                 { "fName"  : "f12", "fFamily": "f12", "fStyle" : "Extrabold Oblique" },

                 { "fName"  : "f13", "fFamily": "f13", "fStyle" : "Italic"  },
                 { "fName"  : "f14", "fFamily": "f14", "fStyle" : "Oblique" },
                 { "fName"  : "f15", "fFamily": "f15", "fStyle" : ""        }
               ]
             }
           })";

    SkMemoryStream stream(json, strlen(json));
    auto fmgr = sk_make_sp<RecordMatchFamilyStyleSkFontMgr>();

    auto anim = Animation::Builder()
                    .setFontManager(fmgr)
                    .setTextShapingFactory(SkShapers::BestAvailable())
                    .make(&stream);

    REPORTER_ASSERT(r, anim);

    static constexpr struct {
        const char*         family;
        SkFontStyle::Weight weight;
        SkFontStyle::Slant  slant;
    } expected[] = {
        { "f1" , SkFontStyle::kNormal_Weight   , SkFontStyle::kUpright_Slant },
        { "f2" , SkFontStyle::kMedium_Weight   , SkFontStyle::kUpright_Slant },
        { "f3" , SkFontStyle::kBold_Weight     , SkFontStyle::kUpright_Slant },
        { "f4" , SkFontStyle::kLight_Weight    , SkFontStyle::kUpright_Slant },
        { "f5" , SkFontStyle::kExtraBold_Weight, SkFontStyle::kUpright_Slant },
        { "f6" , SkFontStyle::kExtraBold_Weight, SkFontStyle::kUpright_Slant },

        { "f7" , SkFontStyle::kNormal_Weight   , SkFontStyle::kItalic_Slant  },
        { "f8" , SkFontStyle::kMedium_Weight   , SkFontStyle::kItalic_Slant  },
        { "f9" , SkFontStyle::kBold_Weight     , SkFontStyle::kItalic_Slant  },
        { "f10", SkFontStyle::kLight_Weight    , SkFontStyle::kOblique_Slant },
        { "f11", SkFontStyle::kExtraBold_Weight, SkFontStyle::kOblique_Slant },
        { "f12", SkFontStyle::kExtraBold_Weight, SkFontStyle::kOblique_Slant },

        { "f13", SkFontStyle::kNormal_Weight   , SkFontStyle::kItalic_Slant  },
        { "f14", SkFontStyle::kNormal_Weight   , SkFontStyle::kOblique_Slant },
        { "f15", SkFontStyle::kNormal_Weight   , SkFontStyle::kUpright_Slant },
    };

    for (const auto& exp : expected) {
        const auto* style = fmgr->styleRequestedWhenMatchingFamily(exp.family);
        REPORTER_ASSERT(r, style);
        REPORTER_ASSERT(r, style->weight() == exp.weight);
        REPORTER_ASSERT(r, style->slant () == exp.slant );
    }
}

DEF_TEST(Skottie_Text_LayoutError, r) {
    // Text node properties:
    //   - scale to fit
    //   - box width: 100
    //   - min font size: 70
    //   - string: Foo Bar Baz
    //
    // Layout should fail with these unsatisfiable constraints.
    static constexpr char json[] =
        R"({
             "v": "5.2.1",
             "w": 100,
             "h": 100,
             "fr": 10,
             "ip": 0,
             "op": 100,
             "fonts": {
               "list": [{
                 "fFamily": "Arial",
                 "fName": "Arial",
                 "fStyle": "Bold"
               }]
             },
             "layers": [{
               "ty": 5,
               "t": {
                 "d": {
                   "k": [{
                     "t": 0,
                     "s": {
                       "f": "Arial",
                       "t": "Foo Bar Baz",
                       "s": 24,
                       "fc": [1,1,1,1],
                       "lh": 70,
                       "ps": [0, 0],
                       "sz": [100, 100],
                       "mf": 70,
                       "rs": 1
                     }
                   }]
                 }
               }
             }]
           })";

    class Logger final : public skottie::Logger {
    public:
        const std::vector<SkString>& errors() const { return fErrors; }

    private:
        void log(Level lvl, const char message[], const char* = nullptr) override {
            if (lvl == Level::kError) {
                fErrors.emplace_back(message);
            }
        }

        std::vector<SkString> fErrors;
    };

    class PortableRP final : public skresources::ResourceProvider {
    private:
        sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override {
            return ToolUtils::CreatePortableTypeface("Serif", SkFontStyle());
        }
    };

    SkMemoryStream stream(json, strlen(json));
    auto logger = sk_make_sp<Logger>();

    auto anim = Animation::Builder()
                    .setLogger(logger)
                    .setResourceProvider(sk_make_sp<PortableRP>())
                    .make(&stream);

    REPORTER_ASSERT(r, anim);
    REPORTER_ASSERT(r, logger->errors().size() == 1);
    REPORTER_ASSERT(r, logger->errors()[0].startsWith("Text layout failed"));
}

DEF_TEST(Skottie_Text_FontFamily, r) {
    static constexpr char json[] =
        R"({
             "v": "5.2.1",
             "w": 100,
             "h": 100,
             "fr": 10,
             "ip": 0,
             "op": 100,
             "fonts": {
               "list": [{
                 "fFamily": "family_1",
                 "fName": "Font1",
                 "fStyle": "Bold"
               }]
             },
             "layers": [{
               "ty": 5,
               "t": {
                 "d": {
                   "k": [{
                     "t": 0,
                     "s": {
                       "f": "Font1",
                       "t": "Foo Bar Baz",
                       "s": 24,
                       "fc": [1,1,1,1],
                       "lh": 70,
                       "ps": [0, 0],
                       "sz": [100, 100],
                       "mf": 70,
                       "rs": 0
                     }
                   }]
                 }
               }
             }]
           })";

    class TextObserver final : public PropertyObserver {
    public:
        const std::unique_ptr<TextPropertyHandle>& text() const { return fText; }

    private:
        void onTextProperty(const char node_name[],
                            const LazyHandle<TextPropertyHandle>& lh) override {
            SkASSERT(!fText); // only one text prop in test
            fText = lh();
        }
        std::unique_ptr<TextPropertyHandle> fText;
    };

    auto fmgr = sk_make_sp<RecordMatchFamilyStyleSkFontMgr>();
    auto prop_observer = sk_make_sp<TextObserver>();

    SkMemoryStream stream(json, strlen(json));
    auto anim = Animation::Builder()
                    .setFontManager(fmgr)
                    .setPropertyObserver(prop_observer)
                    .setTextShapingFactory(SkShapers::BestAvailable())
                    .make(&stream);
    REPORTER_ASSERT(r, anim);

    // Original family name was passed to fontmgr.
    const auto* style1 = fmgr->styleRequestedWhenMatchingFamily("family_1");
    REPORTER_ASSERT(r, style1);

    const auto& text_handle = prop_observer->text();
    REPORTER_ASSERT(r, text_handle);
    auto txt = (*text_handle).get();
    txt.fFontFamily = "family_2";
    (*text_handle).set(txt);

    // Updated family name was passed to fontmgr.
    const auto* style2 = fmgr->styleRequestedWhenMatchingFamily("family_2");
    REPORTER_ASSERT(r, style2);
}
