/*
 * 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 "Test.h"

#include "SkCommandLineFlags.h"
#include "SkFontMgr.h"
#include "SkOTTable_name.h"
#include "SkTypeface.h"

#include <stddef.h>

template <size_t R, size_t D> struct Format0NameTable {
    SkOTTableName header;
    SkOTTableName::Record nameRecord[R];
    char data[D];
};

template <size_t R, size_t L, size_t D> struct Format1NameTable {
    SkOTTableName header;
    SkOTTableName::Record nameRecord[R];
    struct {
        SkOTTableName::Format1Ext header;
        SkOTTableName::Format1Ext::LangTagRecord langTagRecord[L];
    } format1ext;
    char data[D];
};

typedef Format0NameTable<1, 9> SimpleFormat0NameTable;
SimpleFormat0NameTable simpleFormat0NameTable = {
    /*header*/ {
        /*format*/ SkOTTableName::format_0,
        /*count*/ SkTEndianSwap16<1>::value,
        /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat0NameTable, data)>::value,
    },
    /*nameRecord[]*/ {
        /*Record*/ {
            /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
            /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
            /*languageID*/ { SkOTTableName::Record::LanguageID::Windows::English_UnitedStates },
            /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
            /*length*/ SkTEndianSwap16<8>::value,
            /*offset*/ SkTEndianSwap16<0>::value,
        }
    },
    /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t",
};

typedef Format1NameTable<1, 1, 19> SimpleFormat1NameTable;
SimpleFormat1NameTable simpleFormat1NameTable = {
    /*header*/ {
        /*format*/ SkOTTableName::format_1,
        /*count*/ SkTEndianSwap16<1>::value,
        /*stringOffset*/ SkTEndianSwap16<offsetof(SimpleFormat1NameTable, data)>::value,
    },
    /*nameRecord[]*/ {
        /*Record*/ {
            /*platformID*/ { SkOTTableName::Record::PlatformID::Windows },
            /*encodingID*/ { SkOTTableName::Record::EncodingID::Windows::UnicodeBMPUCS2 },
            /*languageID*/ { SkTEndianSwap16<0x8000 + 0>::value },
            /*nameID*/ { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
            /*length*/ SkTEndianSwap16<8>::value,
            /*offset*/ SkTEndianSwap16<0>::value,
        }
    },
    /*format1ext*/ {
        /*header*/ {
            /*langTagCount*/ SkTEndianSwap16<1>::value,
        },
        /*langTagRecord[]*/ {
            /*LangTagRecord*/ {
                /*length*/ SkTEndianSwap16<10>::value,
                /*offset*/ SkTEndianSwap16<8>::value,
            },
        },
    },
    /*data*/ "\x0" "T" "\x0" "e" "\x0" "s" "\x0" "t"
             "\x0" "e" "\x0" "n" "\x0" "-" "\x0" "U" "\x0" "S",
};

struct FontNamesTest {
    SkOTTableName* data;
    SkOTTableName::Record::NameID nameID;
    size_t nameCount;
    struct {
        const char* name;
        const char* language;
    } names[10];

} test[] = {
    {
        (SkOTTableName*)&simpleFormat0NameTable,
        { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
        1,
        {
            { "Test", "en-US" },
        },
    },
    {
        (SkOTTableName*)&simpleFormat1NameTable,
        { SkOTTableName::Record::NameID::Predefined::FontFamilyName },
        1,
        {
            { "Test", "en-US" },
        },
    },
};

static void test_synthetic(skiatest::Reporter* reporter, bool verbose) {
    for (size_t i = 0; i < SK_ARRAY_COUNT(test); ++i) {
        SkOTTableName::Iterator iter(*test[i].data, test[i].nameID.predefined.value);
        SkOTTableName::Iterator::Record record;
        size_t nameIndex = 0;
        while (nameIndex < test[i].nameCount && iter.next(record)) {
            REPORTER_ASSERT_MESSAGE(reporter,
                strcmp(test[i].names[nameIndex].name, record.name.c_str()) == 0,
                "Name did not match."
            );

            REPORTER_ASSERT_MESSAGE(reporter,
                strcmp(test[i].names[nameIndex].language, record.language.c_str()) == 0,
                "Language did not match."
            );

            //printf("%s <%s>\n", record.name.c_str(), record.language.c_str());

            ++nameIndex;
        }

        REPORTER_ASSERT_MESSAGE(reporter, nameIndex == test[i].nameCount,
                                "Fewer names than expected.");

        REPORTER_ASSERT_MESSAGE(reporter, !iter.next(record),
                                "More names than expected.");
    }
}

#define MAX_FAMILIES 1000
static void test_systemfonts(skiatest::Reporter* reporter, bool verbose) {
    static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e');

    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
    int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
    for (int i = 0; i < count; ++i) {
        SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i));
        for (int j = 0; j < set->count(); ++j) {
            SkString sname;
            SkFontStyle fs;
            set->getStyle(j, &fs, &sname);

            SkAutoTUnref<SkTypeface> typeface(set->createTypeface(j));
            if (NULL == typeface.get()) {
                //TODO: SkFontMgr_fontconfig always returns NULL?
                continue;
            }

            SkString familyName;
            typeface->getFamilyName(&familyName);
            if (verbose) {
                printf("[%s]\n", familyName.c_str());
            }

            SkAutoTUnref<SkTypeface::LocalizedStrings> familyNamesIter(
                typeface->createFamilyNameIterator());
            SkTypeface::LocalizedString familyNameLocalized;
            while (familyNamesIter->next(&familyNameLocalized)) {
                if (verbose) {
                    printf("(%s) <%s>\n", familyNameLocalized.fString.c_str(),
                                          familyNameLocalized.fLanguage.c_str());
                }
            }

            size_t nameTableSize = typeface->getTableSize(nameTag);
            if (0 == nameTableSize) {
                continue;
            }
            SkAutoTMalloc<uint8_t> nameTableData(nameTableSize);
            size_t copied = typeface->getTableData(nameTag, 0, nameTableSize, nameTableData.get());
            if (copied != nameTableSize) {
                continue;
            }

            SkOTTableName::Iterator::Record record;
            SkOTTableName::Iterator familyNameIter(*((SkOTTableName*)nameTableData.get()),
                SkOTTableName::Record::NameID::Predefined::FontFamilyName);
            while (familyNameIter.next(record)) {
                REPORTER_ASSERT_MESSAGE(reporter,
                    SkOTTableName::Record::NameID::Predefined::FontFamilyName == record.type,
                    "Requested family name, got something else."
                );
                if (verbose) {
                    printf("{%s} <%s>\n", record.name.c_str(), record.language.c_str());
                }
            }

            SkOTTableName::Iterator styleNameIter(*((SkOTTableName*)nameTableData.get()),
                SkOTTableName::Record::NameID::Predefined::FontSubfamilyName);
            while (styleNameIter.next(record)) {
                REPORTER_ASSERT_MESSAGE(reporter,
                    SkOTTableName::Record::NameID::Predefined::FontSubfamilyName == record.type,
                    "Requested subfamily name, got something else."
                );
                if (verbose) {
                    printf("{{%s}} <%s>\n", record.name.c_str(), record.language.c_str());
                }
            }

            if (verbose) {
                printf("\n");
            }
        }
    }
}

DEFINE_bool(verboseFontNames, false, "verbose FontNames test.");

static void TestFontNames(skiatest::Reporter* reporter) {
    test_synthetic(reporter, FLAGS_verboseFontNames);
    test_systemfonts(reporter, FLAGS_verboseFontNames);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("FontNames", FontNamesTestClass, TestFontNames)
