/*
 * Copyright 2022 Rive
 */

#include "rive/text_engine.hpp"

#ifdef WITH_RIVE_TEXT
#include "rive/text/font_hb.hpp"

#include "rive/factory.hpp"
#include "rive/renderer_utils.hpp"

#include "hb.h"
#include "hb-ot.h"

extern "C"
{
#include "SheenBidi.h"
}

// Initialized to null. Client can set this to a callback.
HBFont::FallbackProc HBFont::gFallbackProc;

rive::rcp<rive::Font> HBFont::Decode(rive::Span<const uint8_t> span)
{
    auto blob = hb_blob_create_or_fail((const char*)span.data(),
                                       (unsigned)span.size(),
                                       HB_MEMORY_MODE_DUPLICATE,
                                       nullptr,
                                       nullptr);
    if (blob)
    {
        auto face = hb_face_create(blob, 0);
        hb_blob_destroy(blob);
        if (face)
        {
            auto font = hb_font_create(face);
            hb_face_destroy(face);
            if (font)
            {
                return rive::rcp<rive::Font>(new HBFont(font));
            }
        }
    }
    return nullptr;
}

//////////////

constexpr int kStdScale = 2048;
constexpr float gInvScale = 1.0f / kStdScale;

extern "C"
{
    static void
    rpath_move_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, float x, float y, void*)
    {
        ((rive::RawPath*)rpath)->moveTo(x * gInvScale, -y * gInvScale);
    }
    static void
    rpath_line_to(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, float x1, float y1, void*)
    {
        ((rive::RawPath*)rpath)->lineTo(x1 * gInvScale, -y1 * gInvScale);
    }
    static void rpath_quad_to(hb_draw_funcs_t*,
                              void* rpath,
                              hb_draw_state_t*,
                              float x1,
                              float y1,
                              float x2,
                              float y2,
                              void*)
    {
        ((rive::RawPath*)rpath)
            ->quadTo(x1 * gInvScale, -y1 * gInvScale, x2 * gInvScale, -y2 * gInvScale);
    }
    static void rpath_cubic_to(hb_draw_funcs_t*,
                               void* rpath,
                               hb_draw_state_t*,
                               float x1,
                               float y1,
                               float x2,
                               float y2,
                               float x3,
                               float y3,
                               void*)
    {
        ((rive::RawPath*)rpath)
            ->cubicTo(x1 * gInvScale,
                      -y1 * gInvScale,
                      x2 * gInvScale,
                      -y2 * gInvScale,
                      x3 * gInvScale,
                      -y3 * gInvScale);
    }
    static void rpath_close(hb_draw_funcs_t*, void* rpath, hb_draw_state_t*, void*)
    {
        ((rive::RawPath*)rpath)->close();
    }
}

static rive::Font::LineMetrics make_lmx(hb_font_t* font)
{
    // premable on font...
    hb_ot_font_set_funcs(font);
    hb_font_set_scale(font, kStdScale, kStdScale);

    hb_font_extents_t extents;
    hb_font_get_h_extents(font, &extents);
    return {-extents.ascender * gInvScale, -extents.descender * gInvScale};
}

HBFont::HBFont(hb_font_t* font) :
    Font(make_lmx(font)), m_Font(font) // we just take ownership, no need to call reference()
{
    m_DrawFuncs = hb_draw_funcs_create();
    hb_draw_funcs_set_move_to_func(m_DrawFuncs, rpath_move_to, nullptr, nullptr);
    hb_draw_funcs_set_line_to_func(m_DrawFuncs, rpath_line_to, nullptr, nullptr);
    hb_draw_funcs_set_quadratic_to_func(m_DrawFuncs, rpath_quad_to, nullptr, nullptr);
    hb_draw_funcs_set_cubic_to_func(m_DrawFuncs, rpath_cubic_to, nullptr, nullptr);
    hb_draw_funcs_set_close_path_func(m_DrawFuncs, rpath_close, nullptr, nullptr);
    hb_draw_funcs_make_immutable(m_DrawFuncs);
}

HBFont::~HBFont()
{
    hb_draw_funcs_destroy(m_DrawFuncs);
    hb_font_destroy(m_Font);
}

rive::Font::Axis HBFont::getAxis(uint16_t index) const
{
    auto face = hb_font_get_face(m_Font);
    assert(index < hb_ot_var_get_axis_count(face));
    unsigned n = 1;
    hb_ot_var_axis_info_t info;
    hb_ot_var_get_axis_infos(face, index, &n, &info);
    assert(n == 1);
    return {info.tag, info.min_value, info.default_value, info.max_value};
}

uint16_t HBFont::getAxisCount() const
{
    auto face = hb_font_get_face(m_Font);
    return (uint16_t)hb_ot_var_get_axis_count(face);
}

std::vector<rive::Font::Coord> HBFont::getCoords() const
{
    auto axes = this->getAxes();
    //  const int count = (int)axes.size();

    unsigned length;
    const float* values = hb_font_get_var_coords_design(m_Font, &length);

    std::vector<rive::Font::Coord> coords(length);
    for (unsigned i = 0; i < length; ++i)
    {
        coords[i] = {axes[i].tag, values[i]};
    }
    return coords;
}

rive::rcp<rive::Font> HBFont::makeAtCoords(rive::Span<const Coord> coords) const
{
    AutoSTArray<16, hb_variation_t> vars(coords.size());
    for (size_t i = 0; i < coords.size(); ++i)
    {
        vars[i] = {coords[i].axis, coords[i].value};
    }
    auto font = hb_font_create_sub_font(m_Font);
    hb_font_set_variations(font, vars.data(), (unsigned int)vars.size());
    return rive::rcp<rive::Font>(new HBFont(font));
}

rive::RawPath HBFont::getPath(rive::GlyphID glyph) const
{
    rive::RawPath rpath;
    hb_font_get_glyph_shape(m_Font, glyph, m_DrawFuncs, &rpath);
    return rpath;
}

///////////////////////////////////////////////////////////

const hb_feature_t gFeatures[] = {
    {'liga', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
    {'dlig', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
    // {'clig', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
    // {'calt', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
    {'kern', 1, HB_FEATURE_GLOBAL_START, HB_FEATURE_GLOBAL_END},
};
constexpr int gNumFeatures = sizeof(gFeatures) / sizeof(gFeatures[0]);

static rive::GlyphRun shape_run(const rive::Unichar text[],
                                const rive::TextRun& tr,
                                unsigned textOffset)
{
    hb_buffer_t* buf = hb_buffer_create();
    hb_buffer_add_utf32(buf, text, tr.unicharCount, 0, tr.unicharCount);

    hb_buffer_set_direction(buf,
                            tr.dir == rive::TextDirection::rtl ? HB_DIRECTION_RTL
                                                               : HB_DIRECTION_LTR);
    hb_buffer_set_script(buf, (hb_script_t)tr.script); // HB_SCRIPT_ARABIC);
    hb_buffer_set_language(buf, hb_language_from_string("fa", -1));

    auto hbfont = (HBFont*)tr.font.get();
    hb_shape(hbfont->m_Font, buf, gFeatures, gNumFeatures);

    unsigned int glyph_count;
    hb_glyph_info_t* glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
    hb_glyph_position_t* glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);

    // todo: check for missing glyphs, and perform font-substitution

    rive::GlyphRun gr(glyph_count);
    gr.font = tr.font;
    gr.size = tr.size;
    gr.styleId = tr.styleId;
    gr.dir = tr.dir;

    const float scale = tr.size / kStdScale;
    for (unsigned int i = 0; i < glyph_count; i++)
    {
        //            hb_position_t x_offset  = glyph_pos[i].x_offset;
        //            hb_position_t y_offset  = glyph_pos[i].y_offset;
        unsigned int index = tr.dir == rive::TextDirection::rtl ? glyph_count - 1 - i : i;
        gr.glyphs[i] = (uint16_t)glyph_info[index].codepoint;
        gr.textIndices[i] = textOffset + glyph_info[index].cluster;
        gr.advances[i] = gr.xpos[i] = glyph_pos[index].x_advance * scale;
    }
    gr.xpos[glyph_count] = 0; // so the next run can line up snug
    hb_buffer_destroy(buf);
    return gr;
}

static rive::GlyphRun extract_subset(const rive::GlyphRun& orig, size_t start, size_t end)
{
    auto count = end - start;
    rive::GlyphRun subset(rive::SimpleArray<rive::GlyphID>(&orig.glyphs[start], count),
                          rive::SimpleArray<uint32_t>(&orig.textIndices[start], count),
                          rive::SimpleArray<float>(&orig.advances[start], count),
                          rive::SimpleArray<float>(&orig.xpos[start], count + 1));
    subset.font = std::move(orig.font);
    subset.size = orig.size;
    subset.dir = orig.dir;
    subset.xpos.back() = 0; // since we're now the end of a run
    subset.styleId = orig.styleId;

    return subset;
}

static void perform_fallback(rive::rcp<rive::Font> fallbackFont,
                             rive::SimpleArrayBuilder<rive::GlyphRun>& gruns,
                             const rive::Unichar text[],
                             const rive::GlyphRun& orig,
                             const rive::TextRun& origTextRun)
{
    assert(orig.glyphs.size() > 0);

    const size_t count = orig.glyphs.size();
    size_t startI = 0;
    while (startI < count)
    {
        size_t endI = startI + 1;
        if (orig.glyphs[startI] == 0)
        {
            while (endI < count && orig.glyphs[endI] == 0)
            {
                ++endI;
            }
            auto textStart = orig.textIndices[startI];
            auto textCount = orig.textIndices[endI - 1] - textStart + 1;
            auto tr = rive::TextRun{
                fallbackFont,
                orig.size,
                textCount,
                origTextRun.script,
                orig.styleId,
                orig.dir,
            };
            gruns.add(shape_run(&text[textStart], tr, textStart));
        }
        else
        {
            while (endI < count && orig.glyphs[endI] != 0)
            {
                ++endI;
            }
            gruns.add(extract_subset(orig, startI, endI));
        }
        startI = endI;
    }
}

rive::SimpleArray<rive::Paragraph> HBFont::onShapeText(rive::Span<const rive::Unichar> text,
                                                       rive::Span<const rive::TextRun> truns) const
{

    rive::SimpleArrayBuilder<rive::Paragraph> paragraphs;
    SBCodepointSequence codepointSequence = {SBStringEncodingUTF32,
                                             (void*)text.data(),
                                             text.size()};

    hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_get_default();

    // Split runs by bidi types.
    uint32_t textIndex = 0;
    uint32_t runIndex = 0;
    uint32_t runStartTextIndex = 0;

    SBUInteger paragraphStart = 0;

    SBAlgorithmRef bidiAlgorithm = SBAlgorithmCreate(&codepointSequence);
    uint32_t unicharIndex = 0;
    uint32_t runTextIndex = 0;

    while (paragraphStart < text.size())
    {
        SBParagraphRef paragraph =
            SBAlgorithmCreateParagraph(bidiAlgorithm, paragraphStart, INT32_MAX, SBLevelDefaultLTR);
        SBUInteger paragraphLength = SBParagraphGetLength(paragraph);
        // Next iteration reads the next paragraph (if any remain).
        paragraphStart += paragraphLength;
        const SBLevel* bidiLevels = SBParagraphGetLevelsPtr(paragraph);
        SBLevel paragraphLevel = SBParagraphGetBaseLevel(paragraph);
        uint32_t paragraphTextIndex = 0;

        std::vector<rive::TextRun> bidiRuns;
        bidiRuns.reserve(truns.size());

        while (runIndex < truns.size())
        {
            const auto& tr = truns[runIndex];
            assert(tr.unicharCount != 0);
            SBLevel lastLevel = bidiLevels[paragraphTextIndex];
            hb_script_t lastScript = hb_unicode_script(ufuncs, text[textIndex]);
            rive::TextRun splitRun = {
                tr.font,
                tr.size,
                tr.unicharCount - runTextIndex,
                (uint32_t)lastScript,
                tr.styleId,
                lastLevel & 1 ? rive::TextDirection::rtl : rive::TextDirection::ltr,
            };

            runStartTextIndex = textIndex;

            runTextIndex++;
            textIndex++;
            paragraphTextIndex++;
            bidiRuns.push_back(splitRun);

            while (runTextIndex < tr.unicharCount && paragraphTextIndex < paragraphLength)
            {
                hb_script_t script = hb_unicode_script(ufuncs, text[textIndex]);
                switch (script)
                {
                    case HB_SCRIPT_COMMON:
                    case HB_SCRIPT_INHERITED:
                        // Propagate last seen "real" script value.
                        script = lastScript;
                        break;
                    default:
                        break;
                }
                if (bidiLevels[paragraphTextIndex] != lastLevel || script != lastScript)
                {
                    lastScript = script;
                    auto& back = bidiRuns.back();
                    back.unicharCount = textIndex - runStartTextIndex;
                    lastLevel = bidiLevels[paragraphTextIndex];

                    rive::TextRun backRun = {
                        back.font,
                        back.size,
                        tr.unicharCount - runTextIndex,
                        (uint32_t)script,
                        back.styleId,
                        lastLevel & 1 ? rive::TextDirection::rtl : rive::TextDirection::ltr,
                    };
                    runStartTextIndex = textIndex;
                    bidiRuns.push_back(backRun);
                }
                runTextIndex++;
                textIndex++;
                paragraphTextIndex++;
            }
            // Reached the end of the run?
            if (runTextIndex == tr.unicharCount)
            {
                runIndex++;
                runTextIndex = 0;
            }
            // We consumed the whole paragraph.
            if (paragraphTextIndex == paragraphLength)
            {
                // Close off the last run.
                auto& back = bidiRuns.back();
                back.unicharCount = textIndex - runStartTextIndex;
                break;
            }
        }

        rive::SimpleArrayBuilder<rive::GlyphRun> gruns(bidiRuns.size());

        for (const auto& tr : bidiRuns)
        {
            auto gr = shape_run(&text[unicharIndex], tr, unicharIndex);
            unicharIndex += tr.unicharCount;

            auto end = gr.glyphs.end();
            auto iter = std::find(gr.glyphs.begin(), end, 0);
            if (!gFallbackProc || iter == end)
            {
                gruns.add(std::move(gr));
            }
            else
            {
                // found at least 1 zero in glyphs, so need to perform font-fallback
                size_t index = iter - gr.glyphs.begin();
                rive::Unichar missing = text[gr.textIndices[index]];
                // todo: consider sending more chars if that helps choose a font
                auto fallback = gFallbackProc({&missing, 1});
                if (fallback)
                {
                    perform_fallback(fallback, gruns, text.data(), gr, tr);
                }
                else
                {
                    gruns.add(std::move(gr)); // oh well, just keep the missing glyphs
                }
            }
        }

        // turn the advances we stored in xpos[] into actual x-positions
        // for logical order.
        float pos = 0;
        for (auto& gr : gruns)
        {
            for (auto& xp : gr.xpos)
            {
                float adv = xp;
                xp = pos;
                pos += adv;
            }
        }

        paragraphs.add({
            std::move(gruns),
            paragraphLevel & 1 ? rive::TextDirection::rtl : rive::TextDirection::ltr,
        });
        SBParagraphRelease(paragraph);
    }

    SBAlgorithmRelease(bidiAlgorithm);
    return paragraphs;
}

bool HBFont::hasGlyph(rive::Span<const rive::Unichar> missing)
{
    hb_codepoint_t glyph;
    return !missing.empty() && hb_font_get_nominal_glyph(m_Font, missing[0], &glyph);
}

#endif
