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

// Running create_test_font generates ./tools/fonts/test_font_index.inc
// and ./tools/fonts/test_font_<generic name>.inc which are read by
// ./tools/fonts/TestFontMgr.cpp

#include "include/core/SkFont.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkPath.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "include/private/SkTArray.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkPathPriv.h"
#include "src/utils/SkOSPath.h"
#include "src/utils/SkUTF.h"

#include <stdio.h>

namespace {

struct NamedFontStyle {
    char const * const fName;
    char const * const fIdentifierName;
    SkFontStyle const fStyle;
};

struct FontDesc {
    NamedFontStyle const fNamedStyle;
    char const * const fFile;
};

struct FontFamilyDesc {
    char const * const fGenericName;
    char const * const fFamilyName;
    char const * const fIdentifierName;
    SkSpan<const FontDesc> const fFonts;
};

} // namespace

static FILE* font_header(const char* family) {
    SkString outPath(SkOSPath::Join(".", "tools"));
    outPath = SkOSPath::Join(outPath.c_str(), "fonts");
    outPath = SkOSPath::Join(outPath.c_str(), "test_font_");
    SkString fam(family);
    do {
        int dashIndex = fam.find("-");
        if (dashIndex < 0) {
            break;
        }
        fam.writable_str()[dashIndex] = '_';
    } while (true);
    outPath.append(fam);
    outPath.append(".inc");
    FILE* out = fopen(outPath.c_str(), "w");

    static const char kHeader[] =
        "/*\n"
        " * Copyright 2015 Google Inc.\n"
        " *\n"
        " * Use of this source code is governed by a BSD-style license that can be\n"
        " * found in the LICENSE file.\n"
        " */\n"
        "\n"
        "// Auto-generated by ";
    fprintf(out, "%s%s\n\n", kHeader, SkOSPath::Basename(__FILE__).c_str());
    return out;
}

enum {
    kMaxLineLength = 80,
};

static ptrdiff_t last_line_length(const SkString& str) {
    const char* first = str.c_str();
    const char* last = first + str.size();
    const char* ptr = last;
    while (ptr > first && *--ptr != '\n')
        ;
    return last - ptr - 1;
}

static void output_fixed(SkScalar num, int emSize, SkString* out) {
    int hex = (int) (num * 65536 / emSize);
    out->appendf("0x%08x,", hex);
    *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
}

static void output_scalar(SkScalar num, int emSize, SkString* out) {
    num /= emSize;
    if (num == (int) num) {
       out->appendS32((int) num);
    } else {
        SkString str;
        str.printf("%1.6g", num);
        int width = (int) str.size();
        const char* cStr = str.c_str();
        while (cStr[width - 1] == '0') {
            --width;
        }
        str.remove(width, str.size() - width);
        out->appendf("%sf", str.c_str());
    }
    *out += ',';
    *out += (int) last_line_length(*out) >= kMaxLineLength ? '\n' : ' ';
}

static int output_points(const SkPoint* pts, int emSize, int count, SkString* ptsOut) {
    for (int index = 0; index < count; ++index) {
        output_scalar(pts[index].fX, emSize, ptsOut);
        output_scalar(pts[index].fY, emSize, ptsOut);
    }
    return count;
}

static void output_path_data(const SkFont& font,
        int emSize, SkString* ptsOut, SkTDArray<SkPath::Verb>* verbs,
        SkTDArray<unsigned>* charCodes, SkTDArray<SkScalar>* widths) {
    for (SkUnichar index = 0x00; index < 0x7f; ++index) {
        uint16_t glyphID = font.unicharToGlyph(index);
        SkPath path;
        font.getPath(glyphID, &path);
        for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
            *verbs->append() = (SkPath::Verb)verb;
            switch (verb) {
                case SkPathVerb::kMove:
                    output_points(&pts[0], emSize, 1, ptsOut);
                    break;
                case SkPathVerb::kLine:
                    output_points(&pts[1], emSize, 1, ptsOut);
                    break;
                case SkPathVerb::kQuad:
                    output_points(&pts[1], emSize, 2, ptsOut);
                    break;
                case SkPathVerb::kCubic:
                    output_points(&pts[1], emSize, 3, ptsOut);
                    break;
                case SkPathVerb::kClose:
                    break;
                default:
                    SkDEBUGFAIL("bad verb");
                    SkASSERT(0);
            }
        }
        *verbs->append() = SkPath::kDone_Verb;
        *charCodes->append() = index;
        SkScalar width;
        font.getWidths(&glyphID, 1, &width);
     // SkASSERT(floor(width) == width);  // not true for Hiragino Maru Gothic Pro
        *widths->append() = width;
        if (0 == index) {
            index = 0x1f;  // skip the rest of the control codes
        }
    }
}

static int offset_str_len(unsigned num) {
    if (num == (unsigned) -1) {
        return 10;
    }
    unsigned result = 1;
    unsigned ref = 10;
    while (ref <= num) {
        ++result;
        ref *= 10;
    }
    return result;
}

static SkString strip_final(const SkString& str) {
    SkString result(str);
    if (result.endsWith("\n")) {
        result.remove(result.size() - 1, 1);
    }
    if (result.endsWith(" ")) {
        result.remove(result.size() - 1, 1);
    }
    if (result.endsWith(",")) {
        result.remove(result.size() - 1, 1);
    }
    return result;
}

static void output_font(sk_sp<SkTypeface> face, const char* identifier, FILE* out) {
    const int emSize = face->getUnitsPerEm() * 2;
    SkFont font;
    font.setEdging(SkFont::Edging::kAntiAlias);
    font.setSize(emSize);
    font.setTypeface(std::move(face));

    SkTDArray<SkPath::Verb> verbs;
    SkTDArray<unsigned> charCodes;
    SkTDArray<SkScalar> widths;
    SkString ptsOut;
    output_path_data(font, emSize, &ptsOut, &verbs, &charCodes, &widths);
    fprintf(out, "const SkScalar %sPoints[] = {\n", identifier);
    ptsOut = strip_final(ptsOut);
    fprintf(out, "%s", ptsOut.c_str());
    fprintf(out, "\n};\n\n");
    fprintf(out, "const unsigned char %sVerbs[] = {\n", identifier);
    int verbCount = verbs.count();
    int outChCount = 0;
    for (int index = 0; index < verbCount;) {
        SkPath::Verb verb = verbs[index];
        SkASSERT(verb >= SkPath::kMove_Verb && verb <= SkPath::kDone_Verb);
        SkASSERT(SkTFitsIn<uint8_t>(verb));
        fprintf(out, "%u", verb);
        if (++index < verbCount) {
            outChCount += 3;
            fprintf(out, "%c", ',');
            if (outChCount >= kMaxLineLength) {
                outChCount = 0;
                fprintf(out, "%c", '\n');
            } else {
                fprintf(out, "%c", ' ');
            }
        }
    }
    fprintf(out, "\n};\n\n");

    // all fonts are now 0x00, 0x20 - 0xFE
    // don't need to generate or output character codes?
    fprintf(out, "const SkUnichar %sCharCodes[] = {\n", identifier);
    int offsetCount = charCodes.count();
    for (int index = 0; index < offsetCount;) {
        unsigned offset = charCodes[index];
        fprintf(out, "%u", offset);
        if (++index < offsetCount) {
            outChCount += offset_str_len(offset) + 2;
            fprintf(out, "%c", ',');
            if (outChCount >= kMaxLineLength) {
                outChCount = 0;
                fprintf(out, "%c", '\n');
            } else {
                fprintf(out, "%c", ' ');
            }
        }
    }
    fprintf(out, "\n};\n\n");

    SkString widthsStr;
    fprintf(out, "const SkFixed %sWidths[] = {\n", identifier);
    for (int index = 0; index < offsetCount; ++index) {
        output_fixed(widths[index], emSize, &widthsStr);
    }
    widthsStr = strip_final(widthsStr);
    fprintf(out, "%s\n};\n\n", widthsStr.c_str());

    fprintf(out, "const size_t %sCharCodesCount = std::size(%sCharCodes);\n\n",
            identifier, identifier);

    SkFontMetrics metrics;
    font.getMetrics(&metrics);
    fprintf(out, "const SkFontMetrics %sMetrics = {\n", identifier);
    SkString metricsStr;
    metricsStr.printf("0x%08x, ", metrics.fFlags);
    output_scalar(metrics.fTop, emSize, &metricsStr);
    output_scalar(metrics.fAscent, emSize, &metricsStr);
    output_scalar(metrics.fDescent, emSize, &metricsStr);
    output_scalar(metrics.fBottom, emSize, &metricsStr);
    output_scalar(metrics.fLeading, emSize, &metricsStr);
    output_scalar(metrics.fAvgCharWidth, emSize, &metricsStr);
    output_scalar(metrics.fMaxCharWidth, emSize, &metricsStr);
    output_scalar(metrics.fXMin, emSize, &metricsStr);
    output_scalar(metrics.fXMax, emSize, &metricsStr);
    output_scalar(metrics.fXHeight, emSize, &metricsStr);
    output_scalar(metrics.fCapHeight, emSize, &metricsStr);
    output_scalar(metrics.fUnderlineThickness, emSize, &metricsStr);
    output_scalar(metrics.fUnderlinePosition, emSize, &metricsStr);
    output_scalar(metrics.fStrikeoutThickness, emSize, &metricsStr);
    output_scalar(metrics.fStrikeoutPosition, emSize, &metricsStr);
    metricsStr = strip_final(metricsStr);
    fprintf(out, "%s\n};\n\n", metricsStr.c_str());
}

static SkString identifier(const FontFamilyDesc& family, const FontDesc& font) {
    SkString id(family.fIdentifierName);
    id.append(font.fNamedStyle.fIdentifierName);
    return id;
}

static void generate_fonts(const char* basepath, const SkSpan<const FontFamilyDesc>& families) {
    FILE* out = nullptr;
    for (const FontFamilyDesc& family : families) {
        out = font_header(family.fGenericName);
        for (const FontDesc& font : family.fFonts) {
            SkString filepath(SkOSPath::Join(basepath, font.fFile));
            SkASSERTF(sk_exists(filepath.c_str()), "The file %s does not exist.", filepath.c_str());
            sk_sp<SkTypeface> resourceTypeface = SkTypeface::MakeFromFile(filepath.c_str());
            SkASSERTF(resourceTypeface, "The file %s is not a font.", filepath.c_str());
            output_font(std::move(resourceTypeface), identifier(family, font).c_str(), out);
        }
        fclose(out);
    }
}

static const char* slant_to_string(SkFontStyle::Slant slant) {
    switch (slant) {
        case SkFontStyle::kUpright_Slant: return "SkFontStyle::kUpright_Slant";
        case SkFontStyle::kItalic_Slant : return "SkFontStyle::kItalic_Slant" ;
        case SkFontStyle::kOblique_Slant: return "SkFontStyle::kOblique_Slant";
        default: SK_ABORT("Unknown slant");
    }
}

static void generate_index(const SkSpan<const FontFamilyDesc>& families,
                           const FontDesc* defaultFont)
{
    FILE* out = font_header("index");
    fprintf(out, "static SkTestFontData gTestFonts[] = {\n");
    for (const FontFamilyDesc& family : families) {
        for (const FontDesc& font : family.fFonts) {
            SkString identifierStr = identifier(family, font);
            const char* identifier = identifierStr.c_str();
            const SkFontStyle& style = font.fNamedStyle.fStyle;
            fprintf(out,
                    "    {    %sPoints, %sVerbs,\n"
                    "         %sCharCodes, %sCharCodesCount, %sWidths,\n"
                    "         %sMetrics, \"Toy %s\", SkFontStyle(%d,%d,%s)\n"
                    "    },\n",
                    identifier, identifier,
                    identifier, identifier, identifier,
                    identifier, family.fFamilyName,
                    style.weight(), style.width(), slant_to_string(style.slant()));
        }
    }
    fprintf(out, "};\n\n");
    fprintf(out,
            "struct SubFont {\n"
            "    const char* fFamilyName;\n"
            "    const char* fStyleName;\n"
            "    SkFontStyle fStyle;\n"
            "    SkTestFontData& fFont;\n"
            "    const char* fFile;\n"
            "};\n\n"
            "const SubFont gSubFonts[] = {\n");
    int defaultIndex = -1;
    int testFontsIndex = 0;
    for (const FontFamilyDesc& family : families) {
        for (const FontDesc& font : family.fFonts) {
            if (&font == defaultFont) {
                defaultIndex = testFontsIndex;
            }
            const SkFontStyle& style = font.fNamedStyle.fStyle;
            fprintf(out,
                    "    { \"%s\", \"%s\", SkFontStyle(%d,%d,%s), gTestFonts[%d], \"%s\" },\n",
                    family.fGenericName, font.fNamedStyle.fName,
                    style.weight(), style.width(), slant_to_string(style.slant()),
                    testFontsIndex, font.fFile);
            testFontsIndex++;
        }
    }
    testFontsIndex = 0;
    for (const FontFamilyDesc& family : families) {
        for (const FontDesc& font : family.fFonts) {
            fprintf(out,
                    "    { \"Toy %s\", \"%s\", SkFontStyle(%d,%d,%s), gTestFonts[%d], \"%s\" },\n",
                    family.fFamilyName, font.fNamedStyle.fName,
                    font.fNamedStyle.fStyle.weight(), font.fNamedStyle.fStyle.width(),
                    slant_to_string(font.fNamedStyle.fStyle.slant()), testFontsIndex, font.fFile);
            testFontsIndex++;
        }
    }
    fprintf(out, "};\n\n");
    SkASSERT(defaultIndex >= 0);
    fprintf(out, "const size_t gDefaultFontIndex = %d;\n", defaultIndex);
    fclose(out);
}

int main(int , char * const []) {
    constexpr NamedFontStyle normal     = {"Normal",      "Normal",     SkFontStyle::Normal()    };
    constexpr NamedFontStyle bold       = {"Bold",        "Bold",       SkFontStyle::Bold()      };
    constexpr NamedFontStyle italic     = {"Italic",      "Italic",     SkFontStyle::Italic()    };
    constexpr NamedFontStyle bolditalic = {"Bold Italic", "BoldItalic", SkFontStyle::BoldItalic()};

    static constexpr FontDesc kMonoFonts[] = {
        {normal,     "LiberationMono-Regular.ttf"},
        {bold,       "LiberationMono-Bold.ttf"},
        {italic,     "LiberationMono-Italic.ttf"},
        {bolditalic, "LiberationMono-BoldItalic.ttf"},
    };

    static constexpr FontDesc kSansFonts[] = {
        {normal,     "LiberationSans-Regular.ttf"},
        {bold,       "LiberationSans-Bold.ttf"},
        {italic,     "LiberationSans-Italic.ttf"},
        {bolditalic, "LiberationSans-BoldItalic.ttf"},
    };

    static constexpr FontDesc kSerifFonts[] = {
        {normal,     "LiberationSerif-Regular.ttf"},
        {bold,       "LiberationSerif-Bold.ttf"},
        {italic,     "LiberationSerif-Italic.ttf"},
        {bolditalic, "LiberationSerif-BoldItalic.ttf"},
    };

    static constexpr FontFamilyDesc kFamiliesData[] = {
        {"monospace",  "Liberation Mono",  "LiberationMono",  kMonoFonts},
        {"sans-serif", "Liberation Sans",  "LiberationSans",  kSansFonts},
        {"serif",      "Liberation Serif", "LiberationSerif", kSerifFonts},
    };

    static constexpr SkSpan<const FontFamilyDesc> kFamilies(kFamiliesData);

#ifdef SK_BUILD_FOR_UNIX
    generate_fonts("/usr/share/fonts/truetype/liberation/", kFamilies);
#else
    generate_fonts("/Library/Fonts/", kFamilies);
#endif
    generate_index(kFamilies, &kFamilies[1].fFonts[0]);
    return 0;
}
