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