/*
 * Copyright 2024 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "include/core/SkFontScanner.h"
#include "src/base/SkAutoMalloc.h"
#include "src/core/SkTHash.h"
#include "src/core/SkWriteBuffer.h"

#include "tests/FontScanner.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/fonts/FontToolUtils.h"

void FontScanner_VariableFont(skiatest::Reporter* reporter,
                                     SkFontScanner* scanner) {
    SkString name = GetResourcePath("fonts/Variable.ttf");

    std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(name.c_str());
    if (!stream) {
         REPORTER_ASSERT(reporter, false, "Cannot open the font file %s\n", name.c_str());
    }

    int numFaces;
    if (!scanner->scanFile(stream.get(), &numFaces)) {
         REPORTER_ASSERT(reporter, false, "Cannot scanFile\n");
    }
    REPORTER_ASSERT(reporter, numFaces == 1);

    skia_private::THashSet<SkFontStyle> uniqueStyles;
    for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
        int numInstances;
        if (!scanner->scanFace(stream.get(), faceIndex, &numInstances)) {
            REPORTER_ASSERT(reporter, false, "Cannot scanFace\n");
            continue;
        }

        REPORTER_ASSERT(reporter, numInstances == 5);
        // Not including the default instance
        for (int instanceIndex = 1; instanceIndex <= numInstances; ++instanceIndex) {
            bool isFixedPitch;
            SkString realName;
            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
            if (!scanner->scanInstance(stream.get(), faceIndex, instanceIndex,
                                       &realName, &style, &isFixedPitch,
                                       nullptr, nullptr)) {
                REPORTER_ASSERT(reporter,
                                false,
                                "Cannot scanInstance %s %d\n",
                                name.c_str(),
                                faceIndex);
                continue;
            } else {
                if (instanceIndex == 0) {
                    // Do not add it to the set
                } else if (uniqueStyles.find(style) == nullptr) {
                    uniqueStyles.add(style);
                } else {
                    REPORTER_ASSERT(
                        reporter,
                        false,
                        "Font: %s (%d %d %d)\n",
                            realName.c_str(), style.weight(), style.width(), style.slant());
                }
            }
        }
        REPORTER_ASSERT(reporter, uniqueStyles.count() == numInstances);
    }
}

void FontScanner_NamedInstances1(skiatest::Reporter* reporter, SkFontScanner* scanner) {
    SkString name = GetResourcePath("fonts/Variable.ttf");

    std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(name.c_str());
    if (!stream) {
        REPORTER_ASSERT(reporter, false, "Cannot open the font file %s\n", name.c_str());
    }

    int numFaces;
    if (!scanner->scanFile(stream.get(), &numFaces)) {
        REPORTER_ASSERT(reporter, false, "Cannot scanFile\n");
    }
    REPORTER_ASSERT(reporter, numFaces == 1);

    skia_private::THashSet<SkFontStyle> uniqueStyles;
    for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
        int numInstances;
        if (!scanner->scanFace(stream.get(), faceIndex, &numInstances)) {
            REPORTER_ASSERT(reporter, false, "Cannot scanFace\n");
            continue;
        }
        REPORTER_ASSERT(reporter, numInstances == 5);
        // Not including the default instance (most time it will be listed anyway)
        for (int instanceIndex = 1; instanceIndex <= numInstances; ++instanceIndex) {
            bool isFixedPitch;
            SkString realName;
            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
            SkFontScanner::AxisDefinitions axes;
            if (!scanner->scanInstance(stream.get(), faceIndex, instanceIndex,
                                       &realName, &style, &isFixedPitch,
                                       &axes, nullptr)) {
                REPORTER_ASSERT(reporter,
                                false,
                                "Cannot scanInstance %s %d\n",
                                name.c_str(),
                                faceIndex);
                continue;
            } else {
                if (uniqueStyles.find(style) == nullptr) {
                    uniqueStyles.add(style);
                    REPORTER_ASSERT(reporter, axes.size() == 2);
                    if (instanceIndex == 5) {
                        SkFourByteTag weight = SkSetFourByteTag('w', 'g', 'h', 't');
                        SkFourByteTag width = SkSetFourByteTag('w', 'd', 't', 'h');
                        REPORTER_ASSERT(reporter, axes[0].tag == weight);
                        REPORTER_ASSERT(reporter, axes[0].def == 400.0f);
                        REPORTER_ASSERT(reporter, axes[0].min == 100.0f);
                        REPORTER_ASSERT(reporter, axes[0].max == 900.0f);
                        REPORTER_ASSERT(reporter, axes[1].tag == width);
                        REPORTER_ASSERT(reporter, axes[1].def == 100.0f);
                        REPORTER_ASSERT(reporter, axes[1].min == 050.0f);
                        REPORTER_ASSERT(reporter, axes[1].max == 200.0f);
                    }
                } else {
                    REPORTER_ASSERT(reporter,
                                    false,
                                    "Font #%d: %s (%d %d %d)\n",
                                    instanceIndex,
                                    realName.c_str(),
                                    style.weight(),
                                    style.width(),
                                    style.slant());
                }
            }
        }
    }
}

void FontScanner_NamedInstances2(skiatest::Reporter* reporter, SkFontScanner* scanner) {
    SkString name = GetResourcePath("fonts/VaryAlongQuads.ttf");

    std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(name.c_str());
    if (!stream) {
        REPORTER_ASSERT(reporter, false, "Cannot open the font file %s\n", name.c_str());
    }

    int numFaces;
    if (!scanner->scanFile(stream.get(), &numFaces)) {
        REPORTER_ASSERT(reporter, false, "Cannot scanFile\n");
    }
    REPORTER_ASSERT(reporter, numFaces == 1);

    for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
        int numInstances;
        if (!scanner->scanFace(stream.get(), faceIndex, &numInstances)) {
            REPORTER_ASSERT(reporter, false, "Cannot scanFace\n");
            continue;
        }
        REPORTER_ASSERT(reporter, numInstances == 3);
        // Not including the default instance (most time it will be listed anyway)
        for (int instanceIndex = 1; instanceIndex <= numInstances; ++instanceIndex) {
            bool isFixedPitch;
            SkString realName;
            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
            SkFontScanner::AxisDefinitions axes;
            if (!scanner->scanInstance(stream.get(), faceIndex, instanceIndex,
                                       &realName, &style, &isFixedPitch,
                                       &axes, nullptr)) {
                REPORTER_ASSERT(reporter,
                                false,
                                "Cannot scanInstance %s %d\n",
                                name.c_str(),
                                faceIndex);
                continue;
            }
            REPORTER_ASSERT(reporter, axes.size() == 2);
            SkFourByteTag weight = SkSetFourByteTag('w', 'g', 'h', 't');
            for (auto i = 0; i < axes.size(); ++i) {
                const auto& axis = axes[i];
                REPORTER_ASSERT(reporter, (instanceIndex != 1) || (style.weight() == 100.0f));
                REPORTER_ASSERT(reporter, (instanceIndex != 2) || (style.weight() == 400.0f));
                REPORTER_ASSERT(reporter, (instanceIndex != 3) || (style.weight() == 900.0f));
                REPORTER_ASSERT(reporter, axis.tag == weight);
                REPORTER_ASSERT(reporter, axis.def == 400.0f);
                REPORTER_ASSERT(reporter, axis.min == 100.0f);
                REPORTER_ASSERT(reporter, axis.max == 900.0f);
            }
        }
    }
}

void FontScanner_FontCollection(skiatest::Reporter* reporter, SkFontScanner* scanner) {
    SkString name = SkString("fonts/test.ttc");
    std::unique_ptr<SkStreamAsset> stream = GetResourceAsStream(name.c_str());
    if (!stream) {
        REPORTER_ASSERT(reporter, false, "Cannot open the font file %s\n", name.c_str());
    }

    int numFaces;
    if (!scanner->scanFile(stream.get(), &numFaces)) {
        REPORTER_ASSERT(reporter, false, "Cannot scanFile\n");
    }
    REPORTER_ASSERT(reporter, numFaces == 2);

    for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
        int numInstances;
        if (!scanner->scanFace(stream.get(), faceIndex, &numInstances)) {
            REPORTER_ASSERT(reporter, false, "Cannot scanFace\n");
            continue;
        }
        REPORTER_ASSERT(reporter, numInstances == 0);
        const auto defaultInstance = 0;
        bool isFixedPitch;
        SkString realName;
        SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
        SkFontScanner::AxisDefinitions axes;
        if (!scanner->scanInstance(stream.get(), faceIndex, defaultInstance,
                                   &realName, &style, &isFixedPitch,
                                   &axes, nullptr)) {
            REPORTER_ASSERT(reporter,
                            false,
                            "Cannot scanInstance %s %d\n",
                            name.c_str(),
                            faceIndex);
            continue;
        }
        REPORTER_ASSERT(reporter, axes.size() == 0);
        REPORTER_ASSERT(reporter, (faceIndex != 0) || (style.weight() == 400.0f));
        REPORTER_ASSERT(reporter, (faceIndex != 1) || (style.weight() == 700.0f));
    }
}
