/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "modules/skshaper/include/SkShaper.h"
#include "modules/skshaper/include/SkShaper_coretext.h"

#ifdef SK_BUILD_FOR_MAC
#import <ApplicationServices/ApplicationServices.h>
#endif

#ifdef SK_BUILD_FOR_IOS
#include <CoreText/CoreText.h>
#include <CoreText/CTFontManager.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#endif

#include "include/ports/SkTypeface_mac.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkUTF.h"
#include "src/utils/mac/SkCGBase.h"
#include "src/utils/mac/SkUniqueCFRef.h"

#include <vector>
#include <utility>

using namespace skia_private;

class SkShaper_CoreText final : public SkShaper {
public:
    explicit SkShaper_CoreText(SkShapers::CT::LineBreakMode lbm) : fLineBreakMode(lbm) {}

private:
#if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
    void shape(const char* utf8, size_t utf8Bytes,
               const SkFont& srcFont,
               bool leftToRight,
               SkScalar width,
               RunHandler*) const override;

    void shape(const char* utf8, size_t utf8Bytes,
               FontRunIterator&,
               BiDiRunIterator&,
               ScriptRunIterator&,
               LanguageRunIterator&,
               SkScalar width,
               RunHandler*) const override;
#endif  // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)

    void shape(const char* utf8, size_t utf8Bytes,
               FontRunIterator&,
               BiDiRunIterator&,
               ScriptRunIterator&,
               LanguageRunIterator&,
               const Feature*, size_t featureSize,
               SkScalar width,
               RunHandler*) const override;

    void shape(SkSpan<const char> utf8,
               FontRunIterator&,
               BiDiRunIterator&,
               ScriptRunIterator&,
               LanguageRunIterator&,
               SkSpan<const Feature>,
               const Options&,
               RunHandler*) const override;

    const SkShapers::CT::LineBreakMode fLineBreakMode;
};

// CTFramesetter/CTFrame can do this, but require version 10.14
class LineBreakIter {
    const CTTypesetterRef fTypesetter;
    const double          fWidth;
    CFIndex               fStart = 0;
    const SkUniqueCFRef<CFStringTokenizerRef> fWordTokenizer;

    static SkUniqueCFRef<CFStringTokenizerRef> MakeWordTokenizer(CFStringRef txt,
                                                                 SkShapers::CT::LineBreakMode lbm) {
        if (lbm != SkShapers::CT::LineBreakMode::kStrict) {
            return nullptr;
        }

        // TODO: plumb a locale arg for more accurate results with complex scripts?
        SkUniqueCFRef<CFLocaleRef> locale(CFLocaleCopyCurrent());

        CFRange full_range = CFRangeMake(0, CFStringGetLength(txt));
        SkUniqueCFRef<CFStringTokenizerRef> tokenizer(
            CFStringTokenizerCreate(kCFAllocatorDefault, txt,
                                    full_range, kCFStringTokenizerUnitWord, locale.get()));

        // Advance to the first word.
        CFStringTokenizerAdvanceToNextToken(tokenizer.get());

        return tokenizer;
    }

    // If the line range happens to break a word, return the range padding needed to include
    // the full word.  This is only done for LineBreakMode::kStrict.
    CFIndex computeWordBreakPadding(const CFRange line_range) {
        if (!fWordTokenizer) {
            return 0;
        }

        CFRange word_range = CFStringTokenizerGetCurrentTokenRange(fWordTokenizer.get());
        if (word_range.location == kCFNotFound) {
            // No words left.
            return 0;
        }

        // Consume words until past current line.
        const CFIndex line_end = line_range.location + line_range.length;
        while (word_range.location < line_end) {
            // Do we have a word break at the end of the current line?
            const CFIndex word_end = word_range.location + word_range.length;
            if (word_range.location < line_end && line_end < word_end) {
                // We should never see a word break for a word starting on the previous line.
                SkASSERT(word_range.location >= line_range.location);

                // Pad the current line with the rest of this word.
                return word_end - line_end;
            }

            if (CFStringTokenizerAdvanceToNextToken(fWordTokenizer.get()) ==
                kCFStringTokenizerTokenNone) {
                // all words consumed, this is the end of the string
                break;
            }
            word_range = CFStringTokenizerGetCurrentTokenRange(fWordTokenizer.get());
        }

        // No word breaks -> no padding.
        return 0;
    }

public:
    LineBreakIter(CFStringRef txt, CTTypesetterRef ts, SkScalar width,
                  SkShapers::CT::LineBreakMode lbm)
        : fTypesetter(ts), fWidth(width), fWordTokenizer(MakeWordTokenizer(txt, lbm)) {}

    SkUniqueCFRef<CTLineRef> nextLine() {
        CFRange line_range {fStart, CTTypesetterSuggestLineBreak(fTypesetter, fStart, fWidth)};
        // Pad to avoid word breaks if needed.
        line_range.length += computeWordBreakPadding(line_range);

        if (!line_range.length) {
            return nullptr;
        }

        fStart += line_range.length;

        return SkUniqueCFRef<CTLineRef>(CTTypesetterCreateLine(fTypesetter, line_range));
    }
};

[[maybe_unused]] static void dict_add_double(CFMutableDictionaryRef d, const void* name, double value) {
    SkUniqueCFRef<CFNumberRef> number(
            CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
    CFDictionaryAddValue(d, name, number.get());
}

static SkUniqueCFRef<CTFontRef> create_ctfont_from_font(const SkFont& font) {
    auto typeface = font.getTypeface();
    auto ctfont = SkTypeface_GetCTFontRef(typeface);
    if (!ctfont) {
        return nullptr;
    }
    return SkUniqueCFRef<CTFontRef>(
            CTFontCreateCopyWithAttributes(ctfont, font.getSize(), nullptr, nullptr));
}

static SkFont run_to_font(CTRunRef run, const SkFont& orig) {
    CFDictionaryRef attr = CTRunGetAttributes(run);
    CTFontRef ct = (CTFontRef)CFDictionaryGetValue(attr, kCTFontAttributeName);
    if (!ct) {
        SkDebugf("no ctfont in Run Attributes\n");
        CFShow(attr);
        return orig;
    }
    // Do I need to add a local cache, or allow the caller to manage this lookup?
    SkFont font(orig);
    font.setTypeface(SkMakeTypefaceFromCTFont(ct));
    return font;
}

namespace {
class UTF16ToUTF8IndicesMap {
public:
    /** Builds a UTF-16 to UTF-8 indices map; the text is not retained
     * @return true if successful
     */
    bool setUTF8(const char* utf8, size_t size) {
        SkASSERT(utf8 != nullptr);

        if (!SkTFitsIn<int32_t>(size)) {
            SkDEBUGF("UTF16ToUTF8IndicesMap: text too long");
            return false;
        }

        auto utf16Size = SkUTF::UTF8ToUTF16(nullptr, 0, utf8, size);
        if (utf16Size < 0) {
            SkDEBUGF("UTF16ToUTF8IndicesMap: Invalid utf8 input");
            return false;
        }

        // utf16Size+1 to also store the size
        fUtf16ToUtf8Indices = std::vector<size_t>(utf16Size + 1);
        auto utf16 = fUtf16ToUtf8Indices.begin();
        auto utf8Begin = utf8, utf8End = utf8 + size;
        while (utf8Begin < utf8End) {
            *utf16 = utf8Begin - utf8;
            utf16 += SkUTF::ToUTF16(SkUTF::NextUTF8(&utf8Begin, utf8End), nullptr);
        }
        *utf16 = size;

        return true;
    }

    size_t mapIndex(size_t index) const {
        SkASSERT(index < fUtf16ToUtf8Indices.size());
        return fUtf16ToUtf8Indices[index];
    }

    std::pair<size_t, size_t> mapRange(size_t start, size_t size) const {
        auto utf8Start = mapIndex(start);
        return {utf8Start, mapIndex(start + size) - utf8Start};
    }
private:
    std::vector<size_t> fUtf16ToUtf8Indices;
};
} // namespace

// kCTTrackingAttributeName not available until 10.12
const CFStringRef kCTTracking_AttributeName = CFSTR("CTTracking");

#if !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)
void SkShaper_CoreText::shape(const char* utf8,
                              size_t utf8Bytes,
                              FontRunIterator& font,
                              BiDiRunIterator& bidi,
                              ScriptRunIterator& script,
                              LanguageRunIterator& lang,
                              SkScalar width,
                              RunHandler* handler) const {
    return this->shape(utf8, utf8Bytes, font, bidi, script, lang, nullptr, 0, width, handler);
}

void SkShaper_CoreText::shape(const char* utf8,
                              size_t utf8Bytes,
                              const SkFont& font,
                              bool,
                              SkScalar width,
                              RunHandler* handler) const {
    std::unique_ptr<FontRunIterator> fontRuns(
            MakeFontMgrRunIterator(utf8, utf8Bytes, font, nullptr));
    if (!fontRuns) {
        return;
    }
    // bidi, script, and lang are all unused so we can construct them with empty data.
    TrivialBiDiRunIterator bidi{0, 0};
    TrivialScriptRunIterator script{0, 0};
    TrivialLanguageRunIterator lang{nullptr, 0};
    return this->shape(utf8, utf8Bytes, *fontRuns, bidi, script, lang, nullptr, 0, width, handler);
}
#endif  // !defined(SK_DISABLE_LEGACY_SKSHAPER_FUNCTIONS)

void SkShaper_CoreText::shape(const char* utf8,
                              size_t utf8Bytes,
                              FontRunIterator& fontRuns,
                              BiDiRunIterator& bidi,
                              ScriptRunIterator& script,
                              LanguageRunIterator& lang,
                              const Feature* features, size_t featuresSize,
                              SkScalar width,
                              RunHandler* handler) const {
    return this->shape({utf8, utf8Bytes}, fontRuns, bidi, script, lang, {features, featuresSize},
                       { .width = width}, handler);
}

void SkShaper_CoreText::shape(SkSpan<const char> utf8,
                              FontRunIterator& fontRuns,
                              BiDiRunIterator&,
                              ScriptRunIterator&,
                              LanguageRunIterator&,
                              SkSpan<const Feature>,
                              const Options& opts,
                              RunHandler* handler) const {
    SkFont font;
    if (!fontRuns.atEnd()) {
        fontRuns.consume();
        font = fontRuns.currentFont();
    }

    SkUniqueCFRef<CFStringRef> textString(
            CFStringCreateWithBytes(kCFAllocatorDefault, (const uint8_t*)utf8.data(), utf8.size(),
                                    kCFStringEncodingUTF8, false));

    UTF16ToUTF8IndicesMap utf8IndicesMap;
    if (!utf8IndicesMap.setUTF8(utf8.data(), utf8.size())) {
        return;
    }

    SkUniqueCFRef<CTFontRef> ctfont = create_ctfont_from_font(font);
    if (!ctfont) {
        return;
    }

    SkUniqueCFRef<CFMutableDictionaryRef> attr(
            CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks));
    CFDictionaryAddValue(attr.get(), kCTFontAttributeName, ctfont.get());
    if (opts.tracking) {
        // Tracking is specified in em units, while CoreText expects absolute values.
        dict_add_double(attr.get(), kCTTracking_AttributeName, opts.tracking * font.getSize());
    }
    if ((false)) {
        // trying to see what these affect
        dict_add_double(attr.get(), kCTTracking_AttributeName, 1);
        dict_add_double(attr.get(), kCTKernAttributeName, 0.0);
    }

    SkUniqueCFRef<CFAttributedStringRef> attrString(
            CFAttributedStringCreate(kCFAllocatorDefault, textString.get(), attr.get()));

    SkUniqueCFRef<CTTypesetterRef> typesetter(
            CTTypesetterCreateWithAttributedString(attrString.get()));

    // We have to compute RunInfos in a loop, and then reuse them in a 2nd loop,
    // so we store them in an array (we reuse the array's storage for each line).
    std::vector<SkFont> fontStorage;
    std::vector<SkShaper::RunHandler::RunInfo> infos;

    LineBreakIter iter(textString.get(), typesetter.get(), opts.width, fLineBreakMode);
    while (SkUniqueCFRef<CTLineRef> line = iter.nextLine()) {
        CFArrayRef run_array = CTLineGetGlyphRuns(line.get());
        CFIndex runCount = CFArrayGetCount(run_array);
        if (runCount == 0) {
            continue;
        }
        handler->beginLine();
        fontStorage.clear();
        fontStorage.reserve(runCount); // ensure the refs won't get invalidated
        infos.clear();
        for (CFIndex j = 0; j < runCount; ++j) {
            CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(run_array, j);
            CFIndex runGlyphs = CTRunGetGlyphCount(run);

            SkASSERT(sizeof(CGGlyph) == sizeof(uint16_t));

            AutoSTArray<4096, CGSize> advances(runGlyphs);
            CTRunGetAdvances(run, {0, runGlyphs}, advances.data());
            SkScalar adv = 0;
            for (CFIndex k = 0; k < runGlyphs; ++k) {
                adv += advances[k].width;
            }

            CFRange cfRange = CTRunGetStringRange(run);
            auto range = utf8IndicesMap.mapRange(cfRange.location, cfRange.length);

            fontStorage.push_back(run_to_font(run, font));
            infos.push_back(SkShaper::RunHandler::RunInfo{
                fontStorage.back(), // info just stores a ref to the font
                0,                  // TODO: need fBidiLevel
                0,                  // TODO: need fScript
                "",                 // TODO: need fLanguage
                {adv, 0},
                (size_t)runGlyphs,
                {range.first, range.second},
            });
            handler->runInfo(infos.back());
        }
        handler->commitRunInfo();

        // Now loop through again and fill in the buffers
        SkScalar lineAdvance = 0;
        for (CFIndex j = 0; j < runCount; ++j) {
            const auto& info = infos[j];
            auto buffer = handler->runBuffer(info);

            CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(run_array, j);
            CFIndex runGlyphs = info.glyphCount;
            SkASSERT(CTRunGetGlyphCount(run) == (CFIndex)info.glyphCount);

            CTRunGetGlyphs(run, {0, runGlyphs}, buffer.glyphs);

            AutoSTArray<4096, CGPoint> positions(runGlyphs);
            CTRunGetPositions(run, {0, runGlyphs}, positions.data());
            AutoSTArray<4096, CFIndex> indices;
            if (buffer.clusters) {
                indices.reset(runGlyphs);
                CTRunGetStringIndices(run, {0, runGlyphs}, indices.data());
            }

            for (CFIndex k = 0; k < runGlyphs; ++k) {
                buffer.positions[k] = {
                    buffer.point.fX + SkScalarFromCGFloat(positions[k].x) - lineAdvance,
                    buffer.point.fY,
                };
                if (buffer.offsets) {
                    buffer.offsets[k] = {0, 0}; // offset relative to the origin for this glyph
                }
                if (buffer.clusters) {
                    buffer.clusters[k] = utf8IndicesMap.mapIndex(indices[k]);
                }
            }
            handler->commitRunBuffer(info);
            lineAdvance += info.fAdvance.fX;
        }
        handler->commitLine();
    }
}

namespace SkShapers::CT {
std::unique_ptr<SkShaper> CoreText(LineBreakMode lbm) {
    return std::make_unique<SkShaper_CoreText>(lbm);
}
}  // namespace SkShapers::CT
