/*
 * Copyright 2014 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontArguments.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/ports/SkFontMgr_android.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFixed.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkTHash.h"
#include "src/ports/SkFontMgr_android_parser.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/flags/CommandLineFlags.h"

#ifdef SK_TYPEFACE_FACTORY_FONTATIONS
#include "include/ports/SkFontScanner_Fontations.h"
#endif
#ifdef SK_TYPEFACE_FACTORY_FREETYPE
#include "include/ports/SkFontScanner_FreeType.h"
#endif

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <memory>
#include <string>

DECLARE_bool(verboseFontMgr)

int CountFallbacks(SkTDArray<FontFamily*> fontFamilies) {
    int countOfFallbackFonts = 0;
    for (int i = 0; i < fontFamilies.size(); i++) {
        if (fontFamilies[i]->fIsFallbackFont) {
            countOfFallbackFonts++;
        }
    }
    return countOfFallbackFonts;
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isALPHA(int c) {
    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}

//https://tools.ietf.org/html/rfc5234#appendix-B.1
static bool isDIGIT(int c) {
    return ('0' <= c && c <= '9');
}

static void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* firstExpectedFile,
                                skiatest::Reporter* reporter) {
    REPORTER_ASSERT(reporter, fontFamilies[0]->fNames.size() == 5);
    REPORTER_ASSERT(reporter, !strcmp(fontFamilies[0]->fNames[0].c_str(), "sans-serif"));
    REPORTER_ASSERT(reporter,
                    !strcmp(fontFamilies[0]->fFonts[0].fFileName.c_str(), firstExpectedFile));
    REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);

    // Check that the languages are all sane.
    for (const auto& fontFamily : fontFamilies) {
        for (const auto& lang : fontFamily->fLanguages) {
            const SkString& langString = lang.getTag();
            for (size_t i = 0; i < langString.size(); ++i) {
                int c = langString[i];
                REPORTER_ASSERT(reporter, isALPHA(c) || isDIGIT(c) || '-' == c);
            }
        }
    }

    // All file names in the test configuration files start with a capital letter.
    // This is not a general requirement, but it is true of all the test configuration data.
    // Verifying ensures the filenames have been read sanely and have not been 'sliced'.
    for (int i = 0; i < fontFamilies.size(); ++i) {
        FontFamily& family = *fontFamilies[i];
        for (int j = 0; j < family.fFonts.size(); ++j) {
            FontFileInfo& file = family.fFonts[j];
            REPORTER_ASSERT(reporter, !file.fFileName.isEmpty() &&
                                      file.fFileName[0] >= 'A' &&
                                      file.fFileName[0] <= 'Z');
        }
    }
}

static void DumpFiles(const FontFamily& fontFamily) {
    for (int j = 0; j < fontFamily.fFonts.size(); ++j) {
        const FontFileInfo& ffi = fontFamily.fFonts[j];
        SkDebugf("  file (%d) %s#%d", ffi.fWeight, ffi.fFileName.c_str(), ffi.fIndex);
        for (const auto& coordinate : ffi.fVariationDesignPosition) {
            SkDebugf(" @'%c%c%c%c'=%f",
                     (char)((coordinate.axis >> 24) & 0xFF),
                     (char)((coordinate.axis >> 16) & 0xFF),
                     (char)((coordinate.axis >> 8) & 0xFF),
                     (char)((coordinate.axis) & 0xFF),
                     coordinate.value);
        }
        SkDebugf("\n");
    }
}

static void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* label) {
    if (!FLAGS_verboseFontMgr) {
        return;
    }

    SkDebugf("\n--- Dumping %s\n", label);
    for (int i = 0; i < fontFamilies.size(); ++i) {
        SkDebugf("Family %d:\n", i);
        switch(fontFamilies[i]->fVariant) {
            case kElegant_FontVariant: SkDebugf("  elegant\n"); break;
            case kCompact_FontVariant: SkDebugf("  compact\n"); break;
            default: break;
        }
        SkDebugf("  basePath %s\n", fontFamilies[i]->fBasePath.c_str());
        if (!fontFamilies[i]->fLanguages.empty()) {
            SkDebugf("  language");
            for (const auto& lang : fontFamilies[i]->fLanguages) {
                SkDebugf(" %s", lang.getTag().c_str());
            }
            SkDebugf("\n");
        }
        for (int j = 0; j < fontFamilies[i]->fNames.size(); ++j) {
            SkDebugf("  name %s\n", fontFamilies[i]->fNames[j].c_str());
        }
        DumpFiles(*fontFamilies[i]);
        for (const auto& [unused, fallbackFamily] : fontFamilies[i]->fallbackFamilies) {
            SkDebugf("  Fallback for: %s\n", fallbackFamily->fFallbackFor.c_str());
            DumpFiles(*fallbackFamily);
        }
    }
    SkDebugf("\n\n");
}

template <int N, typename T> static double test_parse_fixed_r(skiatest::Reporter* reporter,
                                                              double low, double high, double inc)
{
    double SK_FixedMax_double = nextafter(1 << (sizeof(T) * CHAR_BIT - N - 1), 0.0);
    double SK_FixedEpsilon_double = (1.0 / (1 << N));
    double maxError = 0;
    char buffer[64];
    for (double f = low; f < high; f += inc) {
        SkString s;
        // 'sprintf' formatting as expected depends on the current locale being "C".
        // We currently expect tests and tools to run in the "C" locale.
        sprintf(buffer, "%.20f", f);
        T fix;
        bool b = parse_fixed<N>(buffer, &fix);
        if (b) {
            double f2 = fix * SK_FixedEpsilon_double;
            double error = fabs(f - f2);
            REPORTER_ASSERT(reporter,  error <= SK_FixedEpsilon_double);
            maxError = std::max(maxError, error);
        } else {
            REPORTER_ASSERT(reporter, f < -SK_FixedMax_double || SK_FixedMax_double < f);
        }
    }

    //SkDebugf("maxError: %.20f\n", maxError);
    return maxError;
}

static void test_parse_fixed(skiatest::Reporter* reporter) {
    test_parse_fixed_r<27, int32_t>(reporter, -8.1, -7.9, 0.000001);
    test_parse_fixed_r<27, int32_t>(reporter, -0.1, 0.1, 0.000001);
    test_parse_fixed_r<27, int32_t>(reporter, 7.9, 8.1, 0.000001);
    test_parse_fixed_r<16, int32_t>(reporter, -0.125, 0.125, 1.0 / (1 << 19));
    test_parse_fixed_r<16, int32_t>(reporter, -32768.125, -32766.875, 1.0 / (1 << 17));
    test_parse_fixed_r<16, int32_t>(reporter, 32766.875, 32768.125, 1.0 / (1 << 17));
    test_parse_fixed_r<16, int32_t>(reporter, -1.1, 1.1, 0.0001);

    SkFixed fix;
    REPORTER_ASSERT(reporter, !parse_fixed<27>("-17.1", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>("32768", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>("", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>(".", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>("123.", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>("a", &fix));
    REPORTER_ASSERT(reporter, !parse_fixed<16>(".123a", &fix));
}

#ifdef SK_TYPEFACE_FACTORY_FONTATIONS
#define DEF_TEST_FONTATIONS(name, reporter) \
    DEF_TEST(name##Fontations, reporter) { name(reporter, SkFontScanner_Make_Fontations()); }
#else
#define DEF_TEST_FONTATIONS(name, reporter)
#endif

#define DEF_TEST_SCANNERS(name, reporter) \
    static void name(skiatest::Reporter*, std::unique_ptr<SkFontScanner>);                     \
    DEF_TEST(name, reporter) { name(reporter, SkFontScanner_Make_FreeType()); }                \
    DEF_TEST_FONTATIONS(name, reporter)                                                        \
    void name(skiatest::Reporter* reporter, std::unique_ptr<SkFontScanner> fs)

DEF_TEST_SCANNERS(FontMgrAndroidParser, reporter) {
    test_parse_fixed(reporter);

    bool resourcesMissing = false;

    SkTDArray<FontFamily*> preV17FontFamilies;
    SkFontMgr_Android_Parser::GetCustomFontFamilies(preV17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/pre_v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/pre_v17/fallback_fonts.xml").c_str());

    if (preV17FontFamilies.size() > 0) {
        REPORTER_ASSERT(reporter, preV17FontFamilies.size() == 14);
        REPORTER_ASSERT(reporter, CountFallbacks(preV17FontFamilies) == 10);

        DumpLoadedFonts(preV17FontFamilies, "pre version 17");
        ValidateLoadedFonts(preV17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }
    for (FontFamily* p : preV17FontFamilies) {
        delete p;
    }
    preV17FontFamilies.reset();


    SkTDArray<FontFamily*> v17FontFamilies;
    SkFontMgr_Android_Parser::GetCustomFontFamilies(v17FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v17/system_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17/fallback_fonts.xml").c_str(),
        GetResourcePath("android_fonts/v17").c_str());

    if (v17FontFamilies.size() > 0) {
        REPORTER_ASSERT(reporter, v17FontFamilies.size() == 56);
        REPORTER_ASSERT(reporter, CountFallbacks(v17FontFamilies) == 46);

        DumpLoadedFonts(v17FontFamilies, "version 17");
        ValidateLoadedFonts(v17FontFamilies, "Roboto-Regular.ttf", reporter);
    } else {
        resourcesMissing = true;
    }
    for (FontFamily* p : v17FontFamilies) {
        delete p;
    }
    v17FontFamilies.reset();


    SkTDArray<FontFamily*> v22FontFamilies;
    SkFontMgr_Android_Parser::GetCustomFontFamilies(v22FontFamilies,
        SkString("/custom/font/path/"),
        GetResourcePath("android_fonts/v22/fonts.xml").c_str(),
        nullptr);

    if (v22FontFamilies.size() > 0) {
        REPORTER_ASSERT(reporter, v22FontFamilies.size() == 54);
        REPORTER_ASSERT(reporter, CountFallbacks(v22FontFamilies) == 42);

        DumpLoadedFonts(v22FontFamilies, "version 22");
        ValidateLoadedFonts(v22FontFamilies, "Roboto-Thin.ttf", reporter);
    } else {
        resourcesMissing = true;
    }
    for (FontFamily* p : v22FontFamilies) {
        delete p;
    }
    v22FontFamilies.reset();

    if (resourcesMissing) {
        SkDebugf("---- Resource files missing for FontConfigParser test\n");
    }
}

DEF_TEST_SCANNERS(FontMgrAndroidLegacyMakeTypeface, reporter) {
    constexpr char fontsXmlFilename[] = "fonts/fonts.xml";
    SkString basePath = GetResourcePath("fonts/");
    SkString fontsXml = GetResourcePath(fontsXmlFilename);

    if (!sk_exists(fontsXml.c_str())) {
        ERRORF(reporter, "file missing: %s\n", fontsXmlFilename);
        return;
    }

    SkFontMgr_Android_CustomFonts custom;
    custom.fSystemFontUse = SkFontMgr_Android_CustomFonts::kOnlyCustom;
    custom.fBasePath = basePath.c_str();
    custom.fFontsXml = fontsXml.c_str();
    custom.fFallbackFontsXml = nullptr;
    custom.fIsolated = false;

    sk_sp<SkFontMgr> fm(SkFontMgr_New_Android(&custom, std::move(fs)));
    sk_sp<SkTypeface> t(fm->legacyMakeTypeface("non-existent-font", SkFontStyle()));
    REPORTER_ASSERT(reporter, nullptr == t);
}

static int bitmap_compare(const SkBitmap& ref, const SkBitmap& test) {
    int count = 0;
    for (int y = 0; y < test.height(); ++y) {
        for (int x = 0; x < test.width(); ++x) {
            SkColor testColor = test.getColor(x, y);
            SkColor refColor = ref.getColor(x, y);
            if (refColor != testColor) {
                ++count;
            }
        }
    }
    return count;
}

DEF_TEST_SCANNERS(FontMgrAndroidSystemVariableTypeface, reporter) {
    constexpr char fontsXmlFilename[] = "fonts/fonts.xml";
    SkString basePath = GetResourcePath("fonts/");
    SkString fontsXml = GetResourcePath(fontsXmlFilename);

    if (!sk_exists(fontsXml.c_str())) {
        ERRORF(reporter, "file missing: %s\n", fontsXmlFilename);
        return;
    }

    SkFontMgr_Android_CustomFonts custom;
    custom.fSystemFontUse = SkFontMgr_Android_CustomFonts::kOnlyCustom;
    custom.fBasePath = basePath.c_str();
    custom.fFontsXml = fontsXml.c_str();
    custom.fFallbackFontsXml = nullptr;
    custom.fIsolated = false;

    sk_sp<SkFontMgr> fontMgr(SkFontMgr_New_Android(&custom, std::move(fs)));
    // "sans-serif" in "fonts/fonts.xml" is "fonts/Distortable.ttf"
    sk_sp<SkTypeface> typeface(fontMgr->legacyMakeTypeface("sans-serif", SkFontStyle()));

    SkBitmap bitmapStream;
    bitmapStream.allocN32Pixels(64, 64);
    SkCanvas canvasStream(bitmapStream);
    canvasStream.drawColor(SK_ColorWHITE);

    SkBitmap bitmapClone;
    bitmapClone.allocN32Pixels(64, 64);
    SkCanvas canvasClone(bitmapClone);
    canvasStream.drawColor(SK_ColorWHITE);

    SkPaint paint;
    paint.setColor(SK_ColorGRAY);
    paint.setAntiAlias(true);
    constexpr float kTextSize = 20;

    std::unique_ptr<SkStreamAsset> distortableStream(
        GetResourceAsStream("fonts/Distortable.ttf"));
    if (!distortableStream) {
        return;
    }

    SkPoint point = SkPoint::Make(20.0f, 20.0f);
    SkFourByteTag tag = SkSetFourByteTag('w', 'g', 'h', 't');

    for (int i = 0; i < 10; ++i) {
        SkScalar styleValue =
            SkDoubleToScalar(0.5 + i * ((2.0 - 0.5) / 10));
        SkFontArguments::VariationPosition::Coordinate
            coordinates[] = {{tag, styleValue}};
        SkFontArguments::VariationPosition
            position = {coordinates, std::size(coordinates)};

        SkFont fontStream(
            fontMgr->makeFromStream(distortableStream->duplicate(),
                                    SkFontArguments().setVariationDesignPosition(position)),
            kTextSize);
        fontStream.setEdging(SkFont::Edging::kSubpixelAntiAlias);


        SkFont fontClone(
            typeface->makeClone(SkFontArguments().setVariationDesignPosition(position)), kTextSize);
        fontClone.setEdging(SkFont::Edging::kSubpixelAntiAlias);

        constexpr char text[] = "abc";

        canvasStream.drawColor(SK_ColorWHITE);
        canvasStream.drawString(text, point.fX, point.fY, fontStream, paint);

        canvasClone.drawColor(SK_ColorWHITE);
        canvasClone.drawString(text, point.fX, point.fY, fontClone, paint);

        auto count = bitmap_compare(bitmapStream, bitmapClone);
        REPORTER_ASSERT(reporter, count == 0);
    }
}

DEF_TEST_SCANNERS(FontMgrAndroidSystemFallbackFor, reporter) {
    constexpr char fontsXmlFilename[] = "fonts/fonts.xml";
    SkString basePath = GetResourcePath("fonts/");
    SkString fontsXml = GetResourcePath(fontsXmlFilename);

    if (!sk_exists(fontsXml.c_str())) {
        ERRORF(reporter, "file missing: %s\n", fontsXmlFilename);
        return;
    }

    SkFontMgr_Android_CustomFonts custom;
    custom.fSystemFontUse = SkFontMgr_Android_CustomFonts::kOnlyCustom;
    custom.fBasePath = basePath.c_str();
    custom.fFontsXml = fontsXml.c_str();
    custom.fFallbackFontsXml = nullptr;
    custom.fIsolated = false;

    sk_sp<SkFontMgr> fontMgr(SkFontMgr_New_Android(&custom, std::move(fs)));
    // "sans-serif" in "fonts/fonts.xml" is "fonts/Distortable.ttf", which doesn't have a '!'
    // but "TestTTC" has a bold font which does have '!' and is marked as fallback for "sans-serif"
    // and should take precedence over the same font marked as normal weight next to it.
    sk_sp<SkTypeface> typeface(fontMgr->matchFamilyStyleCharacter(
        "sans-serif", SkFontStyle(), nullptr, 0, '!'));

    REPORTER_ASSERT(reporter, typeface->fontStyle() == SkFontStyle::Bold());
}
