#include <cassert>
#include "font.h"
#include "include/core/SkFont.h"

uint16_t RiveFont::charToGlyph(SkUnichar u) const
{
    for (size_t i = 0; i < fCMap.size(); ++i)
    {
        if (fCMap[i].fChar == u)
        {
            return fCMap[i].fGlyph;
        }
    }
    return 0;
}

float RiveFont::advance(uint16_t glyph) const
{
    assert(glyph < fGlyphs.size());
    return fGlyphs[glyph].fAdvance;
}

const SkPath* RiveFont::path(uint16_t glyph) const
{
    assert(glyph < fGlyphs.size());
    const SkPath& p = fGlyphs[glyph].fPath;
    return p.isEmpty() ? nullptr : &p;
}

#define kSignature 0x23581321
#define kVersion 1

constexpr uint32_t Tag(unsigned a, unsigned b, unsigned c, unsigned d)
{
    assert((a & 0xFF) == a);
    assert((b & 0xFF) == b);
    assert((c & 0xFF) == c);
    assert((d & 0xFF) == d);
    return (a << 24) | (b << 16) | (c << 8) | d;
}

static inline void tag_to_str(uint32_t tag, char str[5])
{
    str[0] = (tag >> 24) & 0xFF;
    str[1] = (tag >> 16) & 0xFF;
    str[2] = (tag >> 8) & 0xFF;
    str[3] = (tag >> 0) & 0xFF;
    str[4] = 0;
}

constexpr uint32_t kOffsets_TableTag = Tag('p', 'o', 'f', 'f');
constexpr uint32_t kPaths_TableTag = Tag('p', 'a', 't', 'h');
constexpr uint32_t kCMap_TableTag = Tag('c', 'm', 'a', 'p');
constexpr uint32_t kInfo_TableTag = Tag('i', 'n', 'f', 'o');
constexpr uint32_t kAdvances_TableTag = Tag('h', 'a', 'd', 'v');

struct TableDir
{
    uint32_t tag;
    uint32_t offset;
    uint32_t length;
};

struct FontHead
{
    uint32_t signature;
    uint32_t version;
    uint32_t tableCount;
    // TableDir[dirCount]

    const TableDir* dir() const { return (const TableDir*)(this + 1); }

    const void* findTable(uint32_t tag) const
    {
        auto dir = this->dir();
        for (unsigned i = 0; i < this->tableCount; ++i)
        {
            if (dir[i].tag == tag)
            {
                return (char*)this + dir[i].offset;
            }
        }
        return nullptr;
    }
};

struct InfoTable
{
    uint16_t glyphCount;
    uint16_t upem;
};

struct GlyphOffsetTable
{
    //  uint32_t offsets[glyphCount+1]; // relative to the glyphdata table
};

struct GlyphRec
{
    // uint16_t verbCount;
    // uint16_t pointCount; // if verbCount > 0
    // uint8_t  verbs;       // Move, Line, Quad, Cubic, Close
    // pad16[]
    // uint16_t x,y x,y x,y
};

void RiveFont::load(sk_sp<SkTypeface> tf, const char str[], size_t len)
{
    this->clear();

    SkFont font(std::move(tf), 1.0f);

    uint16_t glyphIDs[len];
    int glyphCount =
        font.textToGlyphs(str, len, SkTextEncoding::kUTF8, glyphIDs, len);
    assert(glyphCount == (int)len);

    struct Rec
    {
        uint16_t charCode;
        uint16_t srcGlyph;
        uint16_t dstGlyph;
    };
    std::vector<Rec> rec;
    uint16_t newDstGlyphID = 1; // leave room for glyphID==0 for missing glyph
    // build vector of unique chars
    for (size_t i = 0; i < len; ++i)
    {
        uint16_t code = str[i];
        auto iter = std::find_if(rec.begin(), rec.end(), [code](const auto& r) {
            return r.charCode == code;
        });
        if (iter == rec.end())
        {
            // gonna add code -- now see if its glyph is unique
            uint16_t srcGlyph = glyphIDs[i];
            auto it2 =
                std::find_if(rec.begin(), rec.end(), [srcGlyph](const auto& r) {
                    return r.srcGlyph == srcGlyph;
                });
            uint16_t dstGlyph;
            if (it2 == rec.end())
            {
                // srcGlyph is unique (or zero)
                dstGlyph = srcGlyph ? newDstGlyphID++ : 0;
            }
            else
            {
                dstGlyph = it2->dstGlyph; // reuse prev dstGlyph
            }
            rec.push_back({code, srcGlyph, dstGlyph});
        }
    }

    std::sort(rec.begin(), rec.end(), [](const Rec& a, const Rec& b) {
        return a.charCode < b.charCode;
    });
    for (const auto& r : rec)
    {
        printf("'%c' [%d] %d -> %d\n",
               r.charCode,
               r.charCode,
               r.srcGlyph,
               r.dstGlyph);
        fCMap.push_back({r.charCode, r.dstGlyph});
    }

    std::sort(rec.begin(), rec.end(), [](const Rec& a, const Rec& b) {
        return a.dstGlyph < b.dstGlyph;
    });

    font.setLinearMetrics(true);
    auto append_glyph = [&](uint16_t srcGlyph) {
        float width;
        font.getWidths(&srcGlyph, 1, &width);
        SkPath path;
        font.getPath(srcGlyph, &path); // returns false if glyph is bitmap

        fGlyphs.push_back({std::move(path), width});
    };

    append_glyph(0); // missing glyph
    for (int i = 1; i < newDstGlyphID; ++i)
    { // walk through our glyphs
        auto iter = std::find_if(rec.begin(), rec.end(), [i](const auto& r) {
            return r.dstGlyph == i;
        });
        assert(iter != rec.end());
        append_glyph(iter->srcGlyph);
    }
}

struct ByteBuilder
{
    std::vector<uint8_t> bytes;

    uint32_t length() const { return bytes.size(); }

    uint8_t add8(size_t x)
    {
        assert((x & 0xFF) == x);
        uint8_t b = (uint8_t)x;
        bytes.push_back(b);
        return b;
    }
    int16_t addS16(ssize_t x)
    {
        int16_t s = (int16_t)x;
        assert(s == x);
        this->add(&s, 2);
        return s;
    }
    uint16_t addU16(size_t x)
    {
        assert((x & 0xFFFF) == x);
        uint16_t u = (uint16_t)x;
        this->add(&u, 2);
        return u;
    }
    uint32_t addU32(size_t x)
    {
        assert((x & 0xFFFFFFFF) == x);
        uint32_t u = (uint32_t)x;
        this->add(&u, 4);
        return u;
    }

    void add(const void* src, size_t n)
    {
        size_t size = bytes.size();
        bytes.resize(size + n);
        memcpy(bytes.data() + size, src, n);
    }
    template <typename T> void add(const std::vector<T>& v)
    {
        this->add(v.data(), v.size() * sizeof(T));
    }
    void add(const ByteBuilder& bb)
    {
        this->add(bb.bytes.data(), bb.bytes.size());
    }
    void add(sk_sp<SkData> data) { this->add(data->data(), data->size()); }

    void padTo16()
    {
        if (bytes.size() & 1)
        {
            this->add8(0);
        }
    }
    void padTo32()
    {
        while (bytes.size() & 3)
        {
            this->add8(0);
        }
    }

    void set32(size_t offset, uint32_t value)
    {
        assert(offset + 4 <= bytes.size());
        assert((offset & 3) == 0);
        memcpy(bytes.data() + offset, &value, 4);
    }

    sk_sp<SkData> detach()
    {
        auto data = SkData::MakeWithCopy(bytes.data(), bytes.size());
        bytes.clear();
        return data;
    }
};

void encode_path(ByteBuilder* bb, const SkPath& path, float scale)
{
    std::vector<uint8_t> varray;
    std::vector<uint16_t> parray;

    auto add_point = [&](SkPoint p) {
        parray.push_back(SkScalarRoundToInt(p.fX * scale));
        parray.push_back(SkScalarRoundToInt(p.fY * scale));
    };

    SkPath::RawIter iter(path);
    for (;;)
    {
        SkPoint pts[4];
        auto verb = iter.next(pts);
        if (verb == SkPath::kDone_Verb)
        {
            break;
        }
        varray.push_back(verb);
        switch ((SkPathVerb)verb)
        {
            case SkPathVerb::kMove:
                add_point(pts[0]);
                break;
            case SkPathVerb::kLine:
                add_point(pts[1]);
                break;
            case SkPathVerb::kQuad:
                add_point(pts[1]);
                add_point(pts[2]);
                break;
            case SkPathVerb::kCubic:
                add_point(pts[1]);
                add_point(pts[2]);
                add_point(pts[3]);
                break;
            case SkPathVerb::kClose:
                break;
            default:
                assert(false); // unsupported
        }
    }
    assert((int)varray.size() == path.countVerbs());
    assert((int)parray.size() == path.countPoints() * 2);

    auto no_useful_verbs = [](const std::vector<uint8_t>& verbs) {
        for (auto v : verbs)
        {
            switch ((SkPathVerb)v)
            {
                case SkPathVerb::kLine:
                case SkPathVerb::kQuad:
                case SkPathVerb::kCubic:
                    return false;
                default:
                    break;
            }
        }
        return true;
    };
    if (no_useful_verbs(varray))
    {
        return; // we signal empty paths with the offset table
    }

    bb->addU16(varray.size());
    assert((parray.size() & 1) == 0);
    bb->addU16(parray.size() / 2); // #points == 2 * #values

    bb->add(varray);
    bb->padTo16();
    bb->add(parray);
}

sk_sp<SkData> RiveFont::encode() const
{
    sk_sp<SkData> infoD, cmapD, offsetsD, pathsD;
    const int upem = 2048;
    const float scale = upem;

    struct DirRec
    {
        uint32_t tag;
        sk_sp<SkData> data;
    };
    std::vector<DirRec> dir;

    {
        InfoTable itable;
        itable.glyphCount = fGlyphs.size();
        itable.upem = upem;
        dir.push_back(
            {kInfo_TableTag, SkData::MakeWithCopy(&itable, sizeof(itable))});
    }

    {
        ByteBuilder cmap;
        // start with #pairs
        cmap.addU16(fCMap.size());
        for (const auto& cm : fCMap)
        {
            cmap.addU16(cm.fChar);
            cmap.addU16(cm.fGlyph);
        }
        dir.push_back({kCMap_TableTag, cmap.detach()});
    }

    // todo: store offset[i] for glyph[i+1] since first offset is always 0
    {
        ByteBuilder paths, advances;
        std::vector<uint32_t> offsets;
        for (const auto& g : fGlyphs)
        {
            offsets.push_back(paths.length());
            encode_path(&paths, g.fPath, scale);
            paths.padTo16();
            advances.addU16(SkScalarRoundToInt(g.fAdvance * scale));
        }
        offsets.push_back(paths.length()); // store N+1 offsets

        dir.push_back(
            {kOffsets_TableTag,
             SkData::MakeWithCopy(offsets.data(), offsets.size() * 4)});
        dir.push_back({kPaths_TableTag, paths.detach()});
        dir.push_back({kAdvances_TableTag, advances.detach()});
    }

    std::sort(dir.begin(), dir.end(), [](const DirRec& a, const DirRec& b) {
        return a.tag < b.tag;
    });

    ByteBuilder header;
    header.addU32(kSignature);
    header.addU32(kVersion);
    header.addU32(dir.size());
    for (auto& d : dir)
    {
        header.addU32(d.tag);
        header.addU32(0); // offset -- fill in later
        header.addU32(d.data->size());
    }

    size_t offsetToDirEntry = sizeof(FontHead);
    for (auto& d : dir)
    {
        // +4 to skip the tag field of the dir entry
        header.set32(offsetToDirEntry + 4, header.length());
        offsetToDirEntry += sizeof(TableDir);

        header.add(d.data);
        header.padTo32();
    }
    return header.detach();
}

struct Reader
{
    const char* fStart;
    const char* fCurr;
    const char* fStop;

    Reader(const void* data, size_t length)
    {
        fStart = (const char*)data;
        fCurr = fStart;
        fStop = fStart + length;
    }

    bool isAvailable(size_t n) const { return fCurr + n <= fStop; }
    size_t available() const { return fStop - fCurr; }

    template <typename T> const T* skip(size_t size)
    {
        assert(this->isAvailable(size));
        const char* p = fCurr;
        fCurr += size;
        return reinterpret_cast<const T*>(p);
    }

    template <typename T> const T* skip() { return this->skip<T>(sizeof(T)); }

    void skip(size_t size) {}

    uint8_t u8()
    {
        assert(this->isAvailable(1));
        return *fCurr++;
    }

    int16_t s16()
    {
        assert(this->isAvailable(2));
        int16_t s;
        memcpy(&s, fCurr, 2);
        fCurr += 2;
        return s;
    }
    uint16_t u16()
    {
        assert(this->isAvailable(2));
        uint16_t s;
        memcpy(&s, fCurr, 2);
        fCurr += 2;
        return s;
    }
    uint32_t u32()
    {
        assert(this->isAvailable(4));
        uint32_t s;
        memcpy(&s, fCurr, 4);
        fCurr += 4;
        return s;
    }

    void read(void* dst, size_t size)
    {
        assert(this->isAvailable(size));
        memcpy(dst, fCurr, size);
        fCurr += size;
    }

    void skipPad16()
    {
        size_t amount = fCurr - fStart;
        if (amount & 1)
        {
            assert(this->isAvailable(1));
            fCurr += 1;
        }
    }
};

static int compute_point_count(const uint8_t verbs[], int verbCount)
{
    int count = 0;
    for (int i = 0; i < verbCount; ++i)
    {
        switch ((SkPathVerb)verbs[i])
        {
            case SkPathVerb::kMove:
                count += 1;
                break;
            case SkPathVerb::kLine:
                count += 1;
                break;
            case SkPathVerb::kQuad:
                count += 2;
                break;
            case SkPathVerb::kCubic:
                count += 3;
                break;
            case SkPathVerb::kClose:
                count += 0;
                break;
            default:
                assert(false);
                return -1;
        }
    }
    return count;
}

static SkPath decode_path(const void* data, size_t length, float scale)
{
    Reader reader(data, length);

    const int verbCount = reader.u16();
    assert(verbCount > 0);
    const int pointCount = reader.u16();

    auto verbs = reader.skip<uint8_t>(verbCount);
    reader.skipPad16();
    const int computedPointCount = compute_point_count(verbs, verbCount);
    assert(pointCount == computedPointCount);

    auto pts16 = reader.skip<int16_t>(pointCount * 2 * sizeof(int16_t));
    assert(reader.available() == 0);

    SkPoint pts[pointCount];
    for (int i = 0; i < pointCount; ++i)
    {
        pts[i] = {pts16[0] * scale, pts16[1] * scale};
        pts16 += 2;
    }

    return SkPath::Make(pts,
                        pointCount,
                        verbs,
                        verbCount,
                        nullptr,
                        0,
                        SkPathFillType::kWinding);
}

bool RiveFont::decode(const void* data, size_t length)
{
    Reader reader(data, length);

    auto font = reader.skip<FontHead>();
    assert(font->signature == kSignature);
    assert(font->version == kVersion);
    assert(font->tableCount >= 0);

    assert(reader.isAvailable(font->tableCount * sizeof(TableDir)));

    if (true)
    {
        auto dir = font->dir();
        for (unsigned i = 0; i < font->tableCount; ++i)
        {
            char str[5];
            tag_to_str(dir[i].tag, str);
            printf("[%d] {%0x08 %s %10d} %d %d\n",
                   i,
                   dir[i].tag,
                   str,
                   dir[i].tag,
                   dir[i].offset,
                   dir[i].length);
        }
    }

    auto info = (const InfoTable*)font->findTable(kInfo_TableTag);
    auto cmap = (const uint16_t*)font->findTable(kCMap_TableTag);
    auto paths = (const char*)font->findTable(kPaths_TableTag);
    auto offsets = (const uint32_t*)font->findTable(kOffsets_TableTag);
    auto advances = (const uint16_t*)font->findTable(kAdvances_TableTag);

    const int glyphCount = info->glyphCount;

    this->clear();

    const int pairCount = *cmap++;
    for (int i = 0; i < pairCount; ++i)
    {
        uint16_t c = *cmap++;
        uint16_t g = *cmap++;
        assert(g < glyphCount);

        fCMap.push_back({c, g});
    }

    const float scale = 1.0f / (float)info->upem;

    for (int i = 0; i < glyphCount; ++i)
    {
        float adv = advances[i] * scale;
        uint32_t start = offsets[i];
        uint32_t end = offsets[i + 1];
        assert(start <= end);

        fGlyphs.push_back({(start == end)
                               ? SkPath()
                               : decode_path(paths + start, end - start, scale),
                           adv});
    }
    return true;
}
