/*
 * Copyright 2013 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/SkData.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "include/ports/SkTypeface_win.h"
#include "include/private/SkFixed.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkFontDescriptor.h"
#include "src/core/SkFontMgrPriv.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkTypefaceCache.h"
#include "src/sfnt/SkOTTable_OS_2.h"
#include "src/sfnt/SkSFNTHeader.h"
#include "src/utils/SkUTF.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/TestEmptyTypeface.h"

#include <memory>

static void TypefaceStyle_test(skiatest::Reporter* reporter,
                               uint16_t weight, uint16_t width, SkData* data)
{
    sk_sp<SkData> dataCopy;
    if (!data->unique()) {
        dataCopy = SkData::MakeWithCopy(data->data(), data->size());
        data = dataCopy.get();
    }
    SkSFNTHeader* sfntHeader = static_cast<SkSFNTHeader*>(data->writable_data());

    SkSFNTHeader::TableDirectoryEntry* tableEntry =
        SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader);
    SkSFNTHeader::TableDirectoryEntry* os2TableEntry = nullptr;
    int numTables = SkEndian_SwapBE16(sfntHeader->numTables);
    for (int tableEntryIndex = 0; tableEntryIndex < numTables; ++tableEntryIndex) {
        if (SkOTTableOS2::TAG == tableEntry[tableEntryIndex].tag) {
            os2TableEntry = tableEntry + tableEntryIndex;
            break;
        }
    }
    SkASSERT_RELEASE(os2TableEntry);

    size_t os2TableOffset = SkEndian_SwapBE32(os2TableEntry->offset);
    SkOTTableOS2_V0* os2Table = SkTAddOffset<SkOTTableOS2_V0>(sfntHeader, os2TableOffset);
    os2Table->usWeightClass.value = SkEndian_SwapBE16(weight);
    using WidthType = SkOTTableOS2_V0::WidthClass::Value;
    os2Table->usWidthClass.value = static_cast<WidthType>(SkEndian_SwapBE16(width));

    sk_sp<SkTypeface> newTypeface(SkTypeface::MakeFromData(sk_ref_sp(data)));
    if (!newTypeface) {
        // Not all SkFontMgr can MakeFromStream().
        return;
    }

    SkFontStyle newStyle = newTypeface->fontStyle();

    //printf("%d, %f\n", weight, (newStyle.weight() - (float)0x7FFF) / (float)0x7FFF);
    //printf("%d, %f\n", width , (newStyle.width()  - (float)0x7F)   / (float)0x7F);
    //printf("%d, %d\n", weight, newStyle.weight());
    //printf("%d, %d\n", width , newStyle.width());

    // Some back-ends (CG, GDI, DW) support OS/2 version A which uses 0 - 10 (but all differently).
    REPORTER_ASSERT(reporter,
                    newStyle.weight() == weight ||
                    (weight <=   10 && newStyle.weight() == 100 * weight) ||
                    (weight ==    4 && newStyle.weight() == 350) ||  // GDI weirdness
                    (weight ==    5 && newStyle.weight() == 400) ||  // GDI weirdness
                    (weight ==    0 && newStyle.weight() ==   1) ||  // DW weirdness
                    (weight == 1000 && newStyle.weight() == 999)     // DW weirdness
    );

    // Some back-ends (GDI) don't support width, ensure these always report 'medium'.
    REPORTER_ASSERT(reporter,
                    newStyle.width() == width ||
                    newStyle.width() == 5);
}
DEF_TEST(TypefaceStyle, reporter) {
    std::unique_ptr<SkStreamAsset> stream(GetResourceAsStream("fonts/Em.ttf"));
    if (!stream) {
        REPORT_FAILURE(reporter, "fonts/Em.ttf", SkString("Cannot load resource"));
        return;
    }
    sk_sp<SkData> data(SkData::MakeFromStream(stream.get(), stream->getLength()));

    using SkFS = SkFontStyle;
    for (int weight = SkFS::kInvisible_Weight; weight <= SkFS::kExtraBlack_Weight; ++weight) {
        TypefaceStyle_test(reporter, weight, 5, data.get());
    }
    for (int width = SkFS::kUltraCondensed_Width; width <= SkFS::kUltraExpanded_Width; ++width) {
        TypefaceStyle_test(reporter, 400, width, data.get());
    }
}

DEF_TEST(TypefacePostScriptName, reporter) {
    sk_sp<SkTypeface> typeface(MakeResourceAsTypeface("fonts/Em.ttf"));
    if (!typeface) {
        // Not all SkFontMgr can MakeFromStream().
        return;
    }

    SkString postScriptName;
    bool hasName = typeface->getPostScriptName(&postScriptName);
    bool hasName2 = typeface->getPostScriptName(nullptr);
    REPORTER_ASSERT(reporter, hasName == hasName2);
    if (hasName) {
        REPORTER_ASSERT(reporter, postScriptName == SkString("Em"));
    }
}

DEF_TEST(TypefaceRoundTrip, reporter) {
    sk_sp<SkTypeface> typeface(MakeResourceAsTypeface("fonts/7630.otf"));
    if (!typeface) {
        // Not all SkFontMgr can MakeFromStream().
        return;
    }

    int fontIndex;
    std::unique_ptr<SkStreamAsset> stream = typeface->openStream(&fontIndex);

    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
    sk_sp<SkTypeface> typeface2 = fm->makeFromStream(std::move(stream), fontIndex);
    REPORTER_ASSERT(reporter, typeface2);
}

DEF_TEST(FontDescriptorNegativeVariationSerialize, reporter) {
    SkFontDescriptor desc;
    SkFontArguments::VariationPosition::Coordinate* variation = desc.setVariationCoordinates(1);
    variation[0] = { 0, -1.0f };

    SkDynamicMemoryWStream stream;
    desc.serialize(&stream);
    SkFontDescriptor descD;
    SkFontDescriptor::Deserialize(stream.detachAsStream().get(), &descD);

    if (descD.getVariationCoordinateCount() != 1) {
        REPORT_FAILURE(reporter, "descD.getVariationCoordinateCount() != 1", SkString());
        return;
    }

    REPORTER_ASSERT(reporter, descD.getVariation()[0].value == -1.0f);
};

DEF_TEST(FontDescriptorDeserializeOldFormat, reporter) {
    // From ossfuzz:26254
    const uint8_t old_serialized_desc[] = {
        0x0, //style
        0xff, 0xfb, 0x0, 0x0, 0x0, // kFontAxes
        0x0, // coordinateCount
        0xff, 0xff, 0x0, 0x0, 0x0, // kSentinel
        0x0, // data length
    };

    SkMemoryStream stream(old_serialized_desc, sizeof(old_serialized_desc), false);
    SkFontDescriptor desc;
    if (!SkFontDescriptor::Deserialize(&stream, &desc)) {
        REPORT_FAILURE(reporter, "!SkFontDescriptor::Deserialize(&stream, &desc)",
                       SkString("bytes should be recognized unless removing support"));
        return;
    }
    // This call should not crash and should not return a valid SkFontData.
    std::unique_ptr<SkFontData> data = desc.maybeAsSkFontData();
    REPORTER_ASSERT(reporter, !data);
};

DEF_TEST(TypefaceAxes, reporter) {
    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
    if (!distortable) {
        REPORT_FAILURE(reporter, "distortable", SkString());
        return;
    }
    constexpr int numberOfAxesInDistortable = 1;

    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
    // The position may be over specified. If there are multiple values for a given axis,
    // ensure the last one since that's what css-fonts-4 requires.
    const SkFontArguments::VariationPosition::Coordinate position[] = {
        { SkSetFourByteTag('w','g','h','t'), 1.618033988749895f },
        { SkSetFourByteTag('w','g','h','t'), SK_ScalarSqrt2 },
    };
    SkFontArguments params;
    params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)});
    // TODO: if axes are set and the back-end doesn't support them, should we create the typeface?
    sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params);

    if (!typeface) {
        return;  // Not all SkFontMgr can makeFromStream().
    }

    int count = typeface->getVariationDesignPosition(nullptr, 0);
    if (count == -1) {
        return;  // The number of axes is unknown.
    }
    REPORTER_ASSERT(reporter, count == numberOfAxesInDistortable);

    // Variable font conservative bounds don't vary, so ensure they aren't reported.
    REPORTER_ASSERT(reporter, typeface->getBounds().isEmpty());

    SkFontArguments::VariationPosition::Coordinate positionRead[numberOfAxesInDistortable];
    count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead));
    if (count == -1) {
        return;  // The position cannot be determined.
    }
    REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(positionRead));

    REPORTER_ASSERT(reporter, positionRead[0].axis == position[1].axis);

    // Convert to fixed for "almost equal".
    SkFixed fixedRead = SkScalarToFixed(positionRead[0].value);
    SkFixed fixedOriginal = SkScalarToFixed(position[1].value);
    REPORTER_ASSERT(reporter, SkTAbs(fixedRead - fixedOriginal) < 2 || // variation set correctly
                              SkTAbs(fixedRead - SK_Fixed1    ) < 2);  // variation remained default
}

DEF_TEST(TypefaceVariationIndex, reporter) {
    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
    if (!distortable) {
        REPORT_FAILURE(reporter, "distortable", SkString());
        return;
    }

    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
    SkFontArguments params;
    // The first named variation position in Distortable is 'Thin'.
    params.setCollectionIndex(0x00010000);
    sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params);
    if (!typeface) {
        // FreeType is the only weird thing that supports this, Skia just needs to make sure if it
        // gets one of these things make sense.
        return;
    }

    int count = typeface->getVariationDesignPosition(nullptr, 0);
    if (!(count == 1)) {
        REPORT_FAILURE(reporter, "count == 1", SkString());
        return;
    }

    SkFontArguments::VariationPosition::Coordinate positionRead[1];
    count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead));
    if (count == -1) {
        return;
    }
    if (!(count == 1)) {
        REPORT_FAILURE(reporter, "count == 1", SkString());
        return;
    }
    REPORTER_ASSERT(reporter, positionRead[0].axis == SkSetFourByteTag('w','g','h','t'));
    REPORTER_ASSERT(reporter, positionRead[0].value == 0.5);
}

DEF_TEST(Typeface, reporter) {

    sk_sp<SkTypeface> t1(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
    sk_sp<SkTypeface> t2(SkTypeface::MakeDefault());

    REPORTER_ASSERT(reporter, SkTypeface::Equal(t1.get(), t2.get()));
    REPORTER_ASSERT(reporter, SkTypeface::Equal(nullptr, t1.get()));
    REPORTER_ASSERT(reporter, SkTypeface::Equal(nullptr, t2.get()));
    REPORTER_ASSERT(reporter, SkTypeface::Equal(t1.get(), nullptr));
    REPORTER_ASSERT(reporter, SkTypeface::Equal(t2.get(), nullptr));
}

DEF_TEST(TypefaceAxesParameters, reporter) {
    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
    if (!distortable) {
        REPORT_FAILURE(reporter, "distortable", SkString());
        return;
    }
    constexpr int numberOfAxesInDistortable = 1;
    constexpr SkScalar minAxisInDistortable = 0.5;
    constexpr SkScalar defAxisInDistortable = 1;
    constexpr SkScalar maxAxisInDistortable = 2;
    constexpr bool axisIsHiddenInDistortable = true;

    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();

    SkFontArguments params;
    sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params);

    if (!typeface) {
        return;  // Not all SkFontMgr can makeFromStream().
    }

    SkFontParameters::Variation::Axis parameter[numberOfAxesInDistortable];
    int count = typeface->getVariationDesignParameters(parameter, SK_ARRAY_COUNT(parameter));
    if (count == -1) {
        return;
    }

    REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(parameter));
    REPORTER_ASSERT(reporter, parameter[0].min == minAxisInDistortable);
    REPORTER_ASSERT(reporter, parameter[0].def == defAxisInDistortable);
    REPORTER_ASSERT(reporter, parameter[0].max == maxAxisInDistortable);
    REPORTER_ASSERT(reporter, parameter[0].tag == SkSetFourByteTag('w','g','h','t'));
    // This seems silly, but allows MSAN to ensure that isHidden is initialized.
    // With GDI or before macOS 10.12, Win10, or FreeType 2.8.1 the API for hidden is missing.
    REPORTER_ASSERT(reporter, parameter[0].isHidden() == axisIsHiddenInDistortable ||
                              parameter[0].isHidden() == false);
}

static bool count_proc(SkTypeface* face, void* ctx) {
    int* count = static_cast<int*>(ctx);
    *count = *count + 1;
    return false;
}
static int count(skiatest::Reporter* reporter, const SkTypefaceCache& cache) {
    int count = 0;
    sk_sp<SkTypeface> none = cache.findByProcAndRef(count_proc, &count);
    REPORTER_ASSERT(reporter, none == nullptr);
    return count;
}

DEF_TEST(TypefaceCache, reporter) {
    sk_sp<SkTypeface> t1(TestEmptyTypeface::Make());
    {
        SkTypefaceCache cache;
        REPORTER_ASSERT(reporter, count(reporter, cache) == 0);
        {
            sk_sp<SkTypeface> t0(TestEmptyTypeface::Make());
            cache.add(t0);
            REPORTER_ASSERT(reporter, count(reporter, cache) == 1);
            cache.add(t1);
            REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
            cache.purgeAll();
            REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
        }
        REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
        cache.purgeAll();
        REPORTER_ASSERT(reporter, count(reporter, cache) == 1);
    }
    REPORTER_ASSERT(reporter, t1->unique());
}

static void check_serialize_behaviors(sk_sp<SkTypeface> tf, bool isLocalData,
                                      skiatest::Reporter* reporter) {
    if (!tf) {
        return;
    }
    auto data0 = tf->serialize(SkTypeface::SerializeBehavior::kDoIncludeData);
    auto data1 = tf->serialize(SkTypeface::SerializeBehavior::kDontIncludeData);
    auto data2 = tf->serialize(SkTypeface::SerializeBehavior::kIncludeDataIfLocal);

    REPORTER_ASSERT(reporter, data0->size() >= data1->size());

    if (isLocalData) {
        REPORTER_ASSERT(reporter, data0->equals(data2.get()));
    } else {
        REPORTER_ASSERT(reporter, data1->equals(data2.get()));
    }
}

DEF_TEST(Typeface_serialize, reporter) {
    check_serialize_behaviors(SkTypeface::MakeDefault(), false, reporter);
    check_serialize_behaviors(SkTypeface::MakeFromStream(
                                         GetResourceAsStream("fonts/Distortable.ttf")),
                              true, reporter);

}

DEF_TEST(Typeface_glyph_to_char, reporter) {
    SkFont font(ToolUtils::emoji_typeface(), 12);
    SkASSERT(font.getTypeface());
    char const * text = ToolUtils::emoji_sample_text();
    size_t const textLen = strlen(text);
    size_t const codepointCount = SkUTF::CountUTF8(text, textLen);
    char const * const textEnd = text + textLen;
    std::unique_ptr<SkUnichar[]> originalCodepoints(new SkUnichar[codepointCount]);
    for (size_t i = 0; i < codepointCount; ++i) {
        originalCodepoints[i] = SkUTF::NextUTF8(&text, textEnd);
    }
    std::unique_ptr<SkGlyphID[]> glyphs(new SkGlyphID[codepointCount]);
    font.unicharsToGlyphs(originalCodepoints.get(), codepointCount, glyphs.get());

    std::unique_ptr<SkUnichar[]> newCodepoints(new SkUnichar[codepointCount]);
    SkFontPriv::GlyphsToUnichars(font, glyphs.get(), codepointCount, newCodepoints.get());

    SkString familyName;
    font.getTypeface()->getFamilyName(&familyName);
    for (size_t i = 0; i < codepointCount; ++i) {
#if defined(SK_BUILD_FOR_WIN)
        // GDI does not support character to glyph mapping outside BMP.
        if (gSkFontMgr_DefaultFactory == &SkFontMgr_New_GDI &&
            0xFFFF < originalCodepoints[i] && newCodepoints[i] == 0)
        {
            continue;
        }
#endif
        // If two codepoints map to the same glyph then this assert is not valid.
        // However, the emoji test font should never have multiple characters map to the same glyph.
        REPORTER_ASSERT(reporter, originalCodepoints[i] == newCodepoints[i],
                        "name:%s i:%zu original:%d new:%d glyph:%d", familyName.c_str(), i,
                        originalCodepoints[i], newCodepoints[i], glyphs[i]);
    }
}

// This test makes sure the legacy typeface creation does not lose its specified
// style. See https://bugs.chromium.org/p/skia/issues/detail?id=8447 for more
// context.
DEF_TEST(LegacyMakeTypeface, reporter) {
    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
    sk_sp<SkTypeface> typeface1 = fm->legacyMakeTypeface(nullptr, SkFontStyle::Italic());
    sk_sp<SkTypeface> typeface2 = fm->legacyMakeTypeface(nullptr, SkFontStyle::Bold());
    sk_sp<SkTypeface> typeface3 = fm->legacyMakeTypeface(nullptr, SkFontStyle::BoldItalic());

    REPORTER_ASSERT(reporter, typeface1->isItalic());
    REPORTER_ASSERT(reporter, !typeface1->isBold());
    REPORTER_ASSERT(reporter, !typeface2->isItalic());
    REPORTER_ASSERT(reporter, typeface2->isBold());
    REPORTER_ASSERT(reporter, typeface3->isItalic());
    REPORTER_ASSERT(reporter, typeface3->isBold());
}
