#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;
}
