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

#include "include/ports/SkFontMgr_fuchsia.h"

#include <fuchsia/fonts/cpp/fidl.h>
#include <lib/zx/vmar.h>
#include <strings.h>
#include <memory>
#include <unordered_map>

#include "src/core/SkFontDescriptor.h"
#include "src/ports/SkFontMgr_custom.h"

#include "include/core/SkFontMgr.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "include/private/SkThreadAnnotations.h"
#include "src/core/SkTypefaceCache.h"

// SkFuchsiaFontDataCache keep track of SkData created from `fuchsia::mem::Buffer` where each buffer
// is identified with a unique identifier. It allows to share the same SkData instances between all
// SkTypeface instances created from the same buffer.
class SkFuchsiaFontDataCache : public SkRefCnt {
public:
    SkFuchsiaFontDataCache() = default;
    ~SkFuchsiaFontDataCache() { SkASSERT(fBuffers.empty()); }

    sk_sp<SkData> GetOrCreateSkData(int bufferId, const fuchsia::mem::Buffer& buffer);

private:
    struct ReleaseSkDataContext {
        sk_sp<SkFuchsiaFontDataCache> fCache;
        int fBufferId;
    };

    static void ReleaseSkData(const void* buffer, void* context);
    void OnBufferDeleted(int bufferId);

    SkMutex fMutex;
    std::unordered_map<int, SkData*> fBuffers SK_GUARDED_BY(fMutex);
};

sk_sp<SkData> SkFuchsiaFontDataCache::GetOrCreateSkData(int bufferId,
                                                        const fuchsia::mem::Buffer& buffer) {
    SkAutoMutexExclusive mutexLock(fMutex);

    auto iter = fBuffers.find(bufferId);
    if (iter != fBuffers.end()) {
        return sk_ref_sp(iter->second);
    }
    auto font_mgr = sk_ref_sp(this);

    uint64_t size = buffer.size;
    uintptr_t mapped_addr = 0;
    zx_status_t status =
            zx::vmar::root_self()->map(ZX_VM_PERM_READ, 0, buffer.vmo, 0, size, &mapped_addr);
    if (status != ZX_OK) return nullptr;

    auto context = new ReleaseSkDataContext{sk_ref_sp(this), bufferId};
    auto data = SkData::MakeWithProc(
            reinterpret_cast<void*>(mapped_addr), size, ReleaseSkData, context);
    SkASSERT(data);

    fBuffers[bufferId] = data.get();
    return data;
}

void SkFuchsiaFontDataCache::OnBufferDeleted(int bufferId) {
    zx_vaddr_t unmap_addr;
    size_t unmap_size;
    {
        SkAutoMutexExclusive mutexLock(fMutex);
        auto it = fBuffers.find(bufferId);
        SkASSERT(it != fBuffers.end());
        unmap_addr = reinterpret_cast<zx_vaddr_t>(it->second->data());
        unmap_size = it->second->size();
        fBuffers.erase(it);
    }

    zx::vmar::root_self()->unmap(unmap_addr, unmap_size);
}

// static
void SkFuchsiaFontDataCache::ReleaseSkData(const void* buffer, void* context) {
    auto releaseSkDataContext = reinterpret_cast<ReleaseSkDataContext*>(context);
    releaseSkDataContext->fCache->OnBufferDeleted(releaseSkDataContext->fBufferId);
    delete releaseSkDataContext;
}

fuchsia::fonts::Slant SkToFuchsiaSlant(SkFontStyle::Slant slant) {
    switch (slant) {
        case SkFontStyle::kOblique_Slant:
            return fuchsia::fonts::Slant::OBLIQUE;
        case SkFontStyle::kItalic_Slant:
            return fuchsia::fonts::Slant::ITALIC;
        case SkFontStyle::kUpright_Slant:
        default:
            return fuchsia::fonts::Slant::UPRIGHT;
    }
}

SkFontStyle::Slant FuchsiaToSkSlant(fuchsia::fonts::Slant slant) {
    switch (slant) {
        case fuchsia::fonts::Slant::OBLIQUE:
            return SkFontStyle::kOblique_Slant;
        case fuchsia::fonts::Slant::ITALIC:
            return SkFontStyle::kItalic_Slant;
        case fuchsia::fonts::Slant::UPRIGHT:
        default:
            return SkFontStyle::kUpright_Slant;
    }
}

fuchsia::fonts::Width SkToFuchsiaWidth(SkFontStyle::Width width) {
    switch (width) {
        case SkFontStyle::Width::kUltraCondensed_Width:
            return fuchsia::fonts::Width::ULTRA_CONDENSED;
        case SkFontStyle::Width::kExtraCondensed_Width:
            return fuchsia::fonts::Width::EXTRA_CONDENSED;
        case SkFontStyle::Width::kCondensed_Width:
            return fuchsia::fonts::Width::CONDENSED;
        case SkFontStyle::Width::kSemiCondensed_Width:
            return fuchsia::fonts::Width::SEMI_CONDENSED;
        case SkFontStyle::Width::kNormal_Width:
            return fuchsia::fonts::Width::NORMAL;
        case SkFontStyle::Width::kSemiExpanded_Width:
            return fuchsia::fonts::Width::SEMI_EXPANDED;
        case SkFontStyle::Width::kExpanded_Width:
            return fuchsia::fonts::Width::EXPANDED;
        case SkFontStyle::Width::kExtraExpanded_Width:
            return fuchsia::fonts::Width::EXTRA_EXPANDED;
        case SkFontStyle::Width::kUltraExpanded_Width:
            return fuchsia::fonts::Width::ULTRA_EXPANDED;
    }
}

// Tries to convert the given integer Skia style width value to the Fuchsia equivalent.
//
// On success, returns true. On failure, returns false, and `outFuchsiaWidth` is left untouched.
bool SkToFuchsiaWidth(int skWidth, fuchsia::fonts::Width* outFuchsiaWidth) {
    if (skWidth < SkFontStyle::Width::kUltraCondensed_Width ||
        skWidth > SkFontStyle::Width::kUltraExpanded_Width) {
        return false;
    }
    auto typedSkWidth = static_cast<SkFontStyle::Width>(skWidth);
    *outFuchsiaWidth = SkToFuchsiaWidth(typedSkWidth);
    return true;
}

SkFontStyle::Width FuchsiaToSkWidth(fuchsia::fonts::Width width) {
    switch (width) {
        case fuchsia::fonts::Width::ULTRA_CONDENSED:
            return SkFontStyle::Width::kUltraCondensed_Width;
        case fuchsia::fonts::Width::EXTRA_CONDENSED:
            return SkFontStyle::Width::kExtraCondensed_Width;
        case fuchsia::fonts::Width::CONDENSED:
            return SkFontStyle::Width::kCondensed_Width;
        case fuchsia::fonts::Width::SEMI_CONDENSED:
            return SkFontStyle::Width::kSemiCondensed_Width;
        case fuchsia::fonts::Width::NORMAL:
            return SkFontStyle::Width::kNormal_Width;
        case fuchsia::fonts::Width::SEMI_EXPANDED:
            return SkFontStyle::Width::kSemiExpanded_Width;
        case fuchsia::fonts::Width::EXPANDED:
            return SkFontStyle::Width::kExpanded_Width;
        case fuchsia::fonts::Width::EXTRA_EXPANDED:
            return SkFontStyle::Width::kExtraExpanded_Width;
        case fuchsia::fonts::Width::ULTRA_EXPANDED:
            return SkFontStyle::Width::kUltraExpanded_Width;
    }
}

fuchsia::fonts::Style2 SkToFuchsiaStyle(const SkFontStyle& style) {
    fuchsia::fonts::Style2 fuchsiaStyle;
    fuchsiaStyle.set_slant(SkToFuchsiaSlant(style.slant())).set_weight(style.weight());

    fuchsia::fonts::Width fuchsiaWidth = fuchsia::fonts::Width::NORMAL;
    if (SkToFuchsiaWidth(style.width(), &fuchsiaWidth)) {
        fuchsiaStyle.set_width(fuchsiaWidth);
    }

    return fuchsiaStyle;
}

constexpr struct {
    const char* fName;
    fuchsia::fonts::GenericFontFamily fGenericFontFamily;
} kGenericFontFamiliesByName[] = {{"serif", fuchsia::fonts::GenericFontFamily::SERIF},
                                  {"sans", fuchsia::fonts::GenericFontFamily::SANS_SERIF},
                                  {"sans-serif", fuchsia::fonts::GenericFontFamily::SANS_SERIF},
                                  {"mono", fuchsia::fonts::GenericFontFamily::MONOSPACE},
                                  {"monospace", fuchsia::fonts::GenericFontFamily::MONOSPACE},
                                  {"cursive", fuchsia::fonts::GenericFontFamily::CURSIVE},
                                  {"fantasy", fuchsia::fonts::GenericFontFamily::FANTASY},
                                  {"system-ui", fuchsia::fonts::GenericFontFamily::SYSTEM_UI},
                                  {"emoji", fuchsia::fonts::GenericFontFamily::EMOJI},
                                  {"math", fuchsia::fonts::GenericFontFamily::MATH},
                                  {"fangsong", fuchsia::fonts::GenericFontFamily::FANGSONG}};

// Tries to find a generic font family with the given name. If none is found, returns false.
bool GetGenericFontFamilyByName(const char* name,
                                fuchsia::fonts::GenericFontFamily* outGenericFamily) {
    if (!name) return false;
    for (auto& genericFamily : kGenericFontFamiliesByName) {
        if (strcasecmp(genericFamily.fName, name) == 0) {
            *outGenericFamily = genericFamily.fGenericFontFamily;
            return true;
        }
    }
    return false;
}

struct TypefaceId {
    uint32_t bufferId;
    uint32_t ttcIndex;

    bool operator==(TypefaceId& other) {
        return std::tie(bufferId, ttcIndex) == std::tie(other.bufferId, other.ttcIndex);
    }
}

constexpr kNullTypefaceId = {0xFFFFFFFF, 0xFFFFFFFF};

class SkTypeface_Fuchsia : public SkTypeface_Stream {
public:
    SkTypeface_Fuchsia(std::unique_ptr<SkFontData> fontData, const SkFontStyle& style,
                       bool isFixedPitch, const SkString familyName, TypefaceId id)
            : SkTypeface_Stream(std::move(fontData), style, isFixedPitch,
                                /*sys_font=*/true, familyName)
            , fId(id) {}

    TypefaceId id() { return fId; }

private:
    TypefaceId fId;
};

sk_sp<SkTypeface> CreateTypefaceFromSkStream(std::unique_ptr<SkStreamAsset> stream,
                                             const SkFontArguments& args, TypefaceId id) {
    using Scanner = SkTypeface_FreeType::Scanner;
    Scanner scanner;
    bool isFixedPitch;
    SkFontStyle style;
    SkString name;
    Scanner::AxisDefinitions axisDefinitions;
    if (!scanner.scanFont(stream.get(), args.getCollectionIndex(), &name, &style, &isFixedPitch,
                          &axisDefinitions)) {
        return nullptr;
    }

    const SkFontArguments::VariationPosition position = args.getVariationDesignPosition();
    SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
    Scanner::computeAxisValues(axisDefinitions, position, axisValues, name);

    auto fontData = std::make_unique<SkFontData>(
        std::move(stream), args.getCollectionIndex(), args.getPalette().index,
        axisValues.get(), axisDefinitions.count(),
        args.getPalette().overrides, args.getPalette().overrideCount);
    return sk_make_sp<SkTypeface_Fuchsia>(std::move(fontData), style, isFixedPitch, name, id);
}

sk_sp<SkTypeface> CreateTypefaceFromSkData(sk_sp<SkData> data, TypefaceId id) {
    return CreateTypefaceFromSkStream(std::make_unique<SkMemoryStream>(std::move(data)),
                                      SkFontArguments().setCollectionIndex(id.ttcIndex), id);
}

class SkFontMgr_Fuchsia final : public SkFontMgr {
public:
    SkFontMgr_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider);
    ~SkFontMgr_Fuchsia() override;

protected:
    // SkFontMgr overrides.
    int onCountFamilies() const override;
    void onGetFamilyName(int index, SkString* familyName) const override;
    SkFontStyleSet* onMatchFamily(const char familyName[]) const override;
    SkFontStyleSet* onCreateStyleSet(int index) const override;
    SkTypeface* onMatchFamilyStyle(const char familyName[], const SkFontStyle&) const override;
    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
                                            const char* bcp47[], int bcp47Count,
                                            SkUnichar character) const override;
    sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override;
    sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
                                            int ttcIndex) const override;
    sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
                                           const SkFontArguments&) const override;
    sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override;
    sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override;

private:
    friend class SkFontStyleSet_Fuchsia;

    sk_sp<SkTypeface> FetchTypeface(const char familyName[], const SkFontStyle& style,
                                    const char* bcp47[], int bcp47Count, SkUnichar character,
                                    bool allow_fallback, bool exact_style_match) const;

    sk_sp<SkTypeface> GetOrCreateTypeface(TypefaceId id, const fuchsia::mem::Buffer& buffer) const;

    mutable fuchsia::fonts::ProviderSyncPtr fFontProvider;

    sk_sp<SkFuchsiaFontDataCache> fBufferCache;

    mutable SkMutex fCacheMutex;
    mutable SkTypefaceCache fTypefaceCache SK_GUARDED_BY(fCacheMutex);
};

class SkFontStyleSet_Fuchsia : public SkFontStyleSet {
public:
    SkFontStyleSet_Fuchsia(sk_sp<SkFontMgr_Fuchsia> font_manager, std::string familyName,
                 std::vector<SkFontStyle> styles)
            : fFontManager(font_manager), fFamilyName(familyName), fStyles(styles) {}

    ~SkFontStyleSet_Fuchsia() override = default;

    int count() override { return fStyles.size(); }

    void getStyle(int index, SkFontStyle* style, SkString* styleName) override {
        SkASSERT(index >= 0 && index < static_cast<int>(fStyles.size()));
        if (style) *style = fStyles[index];

        // We don't have style names. Return an empty name.
        if (styleName) styleName->reset();
    }

    SkTypeface* createTypeface(int index) override {
        SkASSERT(index >= 0 && index < static_cast<int>(fStyles.size()));

        if (fTypefaces.empty()) fTypefaces.resize(fStyles.size());

        if (!fTypefaces[index]) {
            fTypefaces[index] = fFontManager->FetchTypeface(
                    fFamilyName.c_str(), fStyles[index], /*bcp47=*/nullptr,
                    /*bcp47Count=*/0, /*character=*/0,
                    /*allow_fallback=*/false, /*exact_style_match=*/true);
        }

        return SkSafeRef(fTypefaces[index].get());
    }

    SkTypeface* matchStyle(const SkFontStyle& pattern) override { return matchStyleCSS3(pattern); }

private:
    sk_sp<SkFontMgr_Fuchsia> fFontManager;
    std::string fFamilyName;
    std::vector<SkFontStyle> fStyles;
    std::vector<sk_sp<SkTypeface>> fTypefaces;
};

SkFontMgr_Fuchsia::SkFontMgr_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider)
        : fFontProvider(std::move(provider)), fBufferCache(sk_make_sp<SkFuchsiaFontDataCache>()) {}

SkFontMgr_Fuchsia::~SkFontMgr_Fuchsia() = default;

int SkFontMgr_Fuchsia::onCountFamilies() const {
    // Family enumeration is not supported.
    return 0;
}

void SkFontMgr_Fuchsia::onGetFamilyName(int index, SkString* familyName) const {
    // Family enumeration is not supported.
    familyName->reset();
}

SkFontStyleSet* SkFontMgr_Fuchsia::onCreateStyleSet(int index) const {
    // Family enumeration is not supported.
    return nullptr;
}

SkFontStyleSet* SkFontMgr_Fuchsia::onMatchFamily(const char familyName[]) const {
    fuchsia::fonts::FamilyName typedFamilyName;
    typedFamilyName.name = familyName;

    fuchsia::fonts::FontFamilyInfo familyInfo;
    int result = fFontProvider->GetFontFamilyInfo(typedFamilyName, &familyInfo);
    if (result != ZX_OK || !familyInfo.has_styles() || familyInfo.styles().empty()) return nullptr;

    std::vector<SkFontStyle> styles;
    for (auto& style : familyInfo.styles()) {
        styles.push_back(SkFontStyle(style.weight(), FuchsiaToSkWidth(style.width()),
                                     FuchsiaToSkSlant(style.slant())));
    }

    return new SkFontStyleSet_Fuchsia(sk_ref_sp(this), familyInfo.name().name, std::move(styles));
}

SkTypeface* SkFontMgr_Fuchsia::onMatchFamilyStyle(const char familyName[],
                                                  const SkFontStyle& style) const {
    sk_sp<SkTypeface> typeface =
            FetchTypeface(familyName, style, /*bcp47=*/nullptr,
                          /*bcp47Count=*/0, /*character=*/0,
                          /*allow_fallback=*/false, /*exact_style_match=*/false);
    return typeface.release();
}

SkTypeface* SkFontMgr_Fuchsia::onMatchFamilyStyleCharacter(const char familyName[],
                                                           const SkFontStyle& style,
                                                           const char* bcp47[], int bcp47Count,
                                                           SkUnichar character) const {
    sk_sp<SkTypeface> typeface =
            FetchTypeface(familyName, style, bcp47, bcp47Count, character, /*allow_fallback=*/true,
                          /*exact_style_match=*/false);
    return typeface.release();
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
    return makeFromStream(std::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> asset,
                                                           int ttcIndex) const {
    return makeFromStream(std::move(asset), SkFontArguments().setCollectionIndex(ttcIndex));
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> asset,
                                                          const SkFontArguments& args) const {
    return CreateTypefaceFromSkStream(std::move(asset), args, kNullTypefaceId);
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::onMakeFromFile(const char path[], int ttcIndex) const {
    return makeFromStream(std::make_unique<SkFILEStream>(path), ttcIndex);
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::onLegacyMakeTypeface(const char familyName[],
                                                          SkFontStyle style) const {
    return sk_sp<SkTypeface>(matchFamilyStyle(familyName, style));
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::FetchTypeface(const char familyName[],
                                                   const SkFontStyle& style, const char* bcp47[],
                                                   int bcp47Count, SkUnichar character,
                                                   bool allow_fallback,
                                                   bool exact_style_match) const {
    fuchsia::fonts::TypefaceQuery query;
    query.set_style(SkToFuchsiaStyle(style));

    if (bcp47Count > 0) {
        std::vector<fuchsia::intl::LocaleId> languages{};
        for (int i = 0; i < bcp47Count; i++) {
            fuchsia::intl::LocaleId localeId;
            localeId.id = bcp47[i];
            languages.push_back(localeId);
        }
        query.set_languages(std::move(languages));
    }

    if (character) {
        query.set_code_points({static_cast<uint32_t>(character)});
    }

    // If family name is not specified or is a generic family name (e.g. "serif"), then enable
    // fallback; otherwise, pass the family name as is.
    fuchsia::fonts::GenericFontFamily genericFontFamily =
            fuchsia::fonts::GenericFontFamily::SANS_SERIF;
    bool isGenericFontFamily = GetGenericFontFamilyByName(familyName, &genericFontFamily);
    if (!familyName || *familyName == '\0' || isGenericFontFamily) {
        if (isGenericFontFamily) {
            query.set_fallback_family(genericFontFamily);
        }
        allow_fallback = true;
    } else {
        fuchsia::fonts::FamilyName typedFamilyName{};
        typedFamilyName.name = familyName;
        query.set_family(typedFamilyName);
    }

    fuchsia::fonts::TypefaceRequestFlags flags{};
    if (!allow_fallback) flags |= fuchsia::fonts::TypefaceRequestFlags::EXACT_FAMILY;
    if (exact_style_match) flags |= fuchsia::fonts::TypefaceRequestFlags::EXACT_STYLE;

    fuchsia::fonts::TypefaceRequest request;
    request.set_query(std::move(query));
    request.set_flags(flags);

    fuchsia::fonts::TypefaceResponse response;
    int result = fFontProvider->GetTypeface(std::move(request), &response);
    if (result != ZX_OK) return nullptr;

    // The service may return an empty response if there is no font matching the request.
    if (response.IsEmpty()) return nullptr;

    return GetOrCreateTypeface(TypefaceId{response.buffer_id(), response.font_index()},
                               response.buffer());
}

static bool FindByTypefaceId(SkTypeface* cachedTypeface, void* ctx) {
    SkTypeface_Fuchsia* cachedFuchsiaTypeface = static_cast<SkTypeface_Fuchsia*>(cachedTypeface);
    TypefaceId* id = static_cast<TypefaceId*>(ctx);

    return cachedFuchsiaTypeface->id() == *id;
}

sk_sp<SkTypeface> SkFontMgr_Fuchsia::GetOrCreateTypeface(TypefaceId id,
                                                         const fuchsia::mem::Buffer& buffer) const {
    SkAutoMutexExclusive mutexLock(fCacheMutex);

    sk_sp<SkTypeface> cached = fTypefaceCache.findByProcAndRef(FindByTypefaceId, &id);
    if (cached) return cached;

    sk_sp<SkData> data = fBufferCache->GetOrCreateSkData(id.bufferId, buffer);
    if (!data) return nullptr;

    auto result = CreateTypefaceFromSkData(std::move(data), id);
    fTypefaceCache.add(result);
    return result;
}

SK_API sk_sp<SkFontMgr> SkFontMgr_New_Fuchsia(fuchsia::fonts::ProviderSyncPtr provider) {
    return sk_make_sp<SkFontMgr_Fuchsia>(std::move(provider));
}
