/*
 * 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 "fuzz/Fuzz.h"
#include "fuzz/FuzzCommon.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "modules/skparagraph/include/DartTypes.h"
#include "modules/skparagraph/include/FontCollection.h"
#include "modules/skparagraph/include/Paragraph.h"
#include "modules/skparagraph/include/ParagraphCache.h"
#include "modules/skparagraph/include/ParagraphStyle.h"
#include "modules/skparagraph/include/TextShadow.h"
#include "modules/skparagraph/include/TextStyle.h"
#include "modules/skparagraph/include/TypefaceFontProvider.h"
#include "modules/skparagraph/src/ParagraphBuilderImpl.h"
#include "modules/skparagraph/src/ParagraphImpl.h"
#include "modules/skparagraph/src/Run.h"
#include "modules/skparagraph/src/TextLine.h"
#include "modules/skparagraph/utils/TestFontCollection.h"
#include "modules/skshaper/utils/FactoryHelpers.h"
#include "src/core/SkOSFile.h"
#include "src/utils/SkOSPath.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/fonts/FontToolUtils.h"

#include <string.h>
#include <algorithm>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#if defined(SK_ENABLE_PARAGRAPH)

using namespace skia::textlayout;
namespace {
const uint8_t MAX_TEXT_LENGTH = 255;
const uint8_t MAX_TEXT_ADDITIONS = 4;
// Use 250 so uint8 can create text and layout width larger than the canvas.
const uint16_t TEST_CANVAS_DIM = 250;

class ResourceFontCollection : public FontCollection {
public:
    ResourceFontCollection(bool testOnly = false)
            : fFontsFound(false)
            , fResolvedFonts(0)
            , fResourceDir(GetResourcePath("fonts").c_str())
            , fFontProvider(sk_make_sp<TypefaceFontProvider>()) {
        std::vector<SkString> fonts;
        SkOSFile::Iter iter(fResourceDir.c_str());

        SkString path;
        sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
        while (iter.next(&path)) {
            if (path.endsWith("Roboto-Italic.ttf")) {
                fFontsFound = true;
            }
            fonts.emplace_back(path);
        }

        if (!fFontsFound) {
            // SkDebugf("Fonts not found, skipping all the tests\n");
            return;
        }
        // Only register fonts if we have to
        for (auto& font : fonts) {
            SkString file_path;
            file_path.printf("%s/%s", fResourceDir.c_str(), font.c_str());
            fFontProvider->registerTypeface(mgr->makeFromFile(file_path.c_str(), 0));
        }

        if (testOnly) {
            this->setTestFontManager(std::move(fFontProvider));
        } else {
            this->setAssetFontManager(std::move(fFontProvider));
        }
        this->disableFontFallback();
    }

    size_t resolvedFonts() const { return fResolvedFonts; }

    // TODO: temp solution until we check in fonts
    bool fontsFound() const { return fFontsFound; }

private:
    bool fFontsFound;
    size_t fResolvedFonts;
    std::string fResourceDir;
    sk_sp<TypefaceFontProvider> fFontProvider;
};

// buffer must be at least MAX_TEXT_LENGTH in length.
// Returns size of text placed in buffer.
template <typename T>
uint8_t RandomText(T* buffer, Fuzz* fuzz) {
    uint8_t text_length;
    fuzz->nextRange(&text_length, 0, MAX_TEXT_LENGTH);
    fuzz->nextN(buffer, text_length);
    return text_length;
}

// Add random bytes to the paragraph.
void AddASCIIText(ParagraphBuilder* builder,Fuzz* fuzz) {
    char text[MAX_TEXT_LENGTH];
    const auto text_length = RandomText(text, fuzz);
    builder->addText(text, text_length);
}
// Add random bytes to the paragraph.
void AddUnicodeText(ParagraphBuilder* builder,Fuzz* fuzz) {
    char16_t text[MAX_TEXT_LENGTH];
    const auto text_length = RandomText(text, fuzz);
    builder->addText(std::u16string(text, text_length));
}

// Combining characters to produce 'Zalgo' text.
const std::u16string COMBINING_DOWN = u"\u0316\u0317\u0318\u0319\u031c\u031d\u031e\u031f\u0320\u0324\u0325\u0326\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u0330\u0331\u0332\u0333\u0339\u033a\u033b\u033c\u0345\u0347\u0348\u0349\u034d\u034e\u0353\u0354\u0355\u0356\u0359\u035a\u0323";
const std::u16string COMBINING_UP = u"\u030d\u030e\u0304\u0305\u033f\u0311\u0306\u0310\u0352\u0357\u0351\u0307\u0308\u030a\u0342\u0343\u0344\u034a\u034b\u034c\u0303\u0302\u030c\u0350\u0300\u0301\u030b\u030f\u0312\u0313\u0314\u033d\u0309\u0363\u0364\u0365\u0366\u0367\u0368\u0369\u036a\u036b\u036c\u036d\u036e\u035b\u0346\u031a";
const std::u16string COMBINING_MIDDLE = u"\u0315\u031b\u0340\u0341\u0358\u0321\u0322\u0327\u0328\u0334\u0335\u0336\u034f\u035c\u035d\u035e\u035f\u0360\u0362\u0338\u0337\u0361\u0489";
// Add random Zalgo text to the paragraph.
void AddZalgoText(ParagraphBuilder* builder, Fuzz* fuzz) {
    char text[MAX_TEXT_LENGTH];
    const auto text_length = RandomText(text, fuzz);
    std::u16string result;

    for (auto& c : std::string(text, text_length)) {
        result += c;
        uint8_t mark_count;
        fuzz->next(&mark_count);
        for (int i = 0; i < mark_count; i++) {
            uint8_t mark_type, mark_index;
            fuzz->next(&mark_type, &mark_index);
            switch (mark_type % 3) {
                case 0:
                    result += COMBINING_UP[mark_index % COMBINING_UP.size()];
                    break;
                case 1:
                    result += COMBINING_MIDDLE[mark_index % COMBINING_MIDDLE.size()];
                    break;
                case 2:
                default:
                    result += COMBINING_DOWN[mark_index % COMBINING_DOWN.size()];
                    break;
            }
        }
    }
    builder->addText(result);
}

void AddStyle(ParagraphBuilder* builder, Fuzz*  fuzz) {
    // TODO(westont): Make this probabilistic, and fill in the remaining TextStyle fields.
    TextStyle ts;
    ts.setFontFamilies({SkString("Roboto")});
    //ts.setColor(SK_ColorBLACK);
    //ts.setForegroundColor
    //ts.setBackgroundColor
    //ts.setDecoration(TextDecoration decoration);
    //ts.setDecorationMode(TextDecorationMode mode);
    //ts.setDecorationStyle(TextDecorationStyle style);
    //ts.setDecorationColor(SkColor color);
    //ts.setDecorationThicknessMultiplier(SkScalar m);
    //ts.setFontStyle
    //ts.addShadow
    //ts.addFontFeature
    //ts.setFontSize
    //ts.setHeight
    //ts.setHeightOverride
    //ts.setletterSpacing
    //ts.setWordSpacing
    //ts.setTypeface
    //ts.setLocale
    //ts.setTextBaseline
    //ts.setPlaceholder

    builder->pushStyle(ts);
}
void RemoveStyle(ParagraphBuilder* builder, Fuzz*  fuzz) {
    bool pop;
    fuzz->next(&pop);
    if (pop) {
        builder->pop();
    }
}

void AddStyleAndText(ParagraphBuilder* builder, Fuzz*  fuzz) {
    AddStyle(builder, fuzz);
    uint8_t text_type;
    fuzz->next(&text_type);
    switch (text_type % 3) {
        case 0:
            AddASCIIText(builder, fuzz);
            break;
        case 1:
            AddUnicodeText(builder, fuzz);
            break;
        case 2:
            AddZalgoText(builder, fuzz);
            break;
    }
    RemoveStyle(builder, fuzz);

}

ParagraphStyle BuildParagraphStyle(Fuzz* fuzz) {
    ParagraphStyle ps;
    bool hinting;
    fuzz->next(&hinting);
    if (hinting) {
        ps.turnHintingOff();
    }
    StrutStyle ss;
    // TODO(westont): Fuzz this object.
    ps.setStrutStyle(ss);
    TextDirection td;
    fuzz->nextEnum(&td, TextDirection::kRtl);
    ps.setTextDirection(td);
    TextAlign ta;
    fuzz->nextEnum(&ta, TextAlign::kEnd);
    ps.setTextAlign(ta);
    size_t ml;
    fuzz->next(&ml);
    ps.setMaxLines(ml);
    // TODO(westont): Randomize with other values and no value.
    ps.setEllipsis(u"\u2026");
    SkScalar h;
    fuzz->next(&h);
    ps.setHeight(h);
    TextHeightBehavior thb = TextHeightBehavior::kAll;
    // TODO(westont): This crashes our seed test case, why?
    //fuzz->nextEnum(&thb, TextHeightBehavior::kDisableAll);
    ps.setTextHeightBehavior(thb);

    return ps;
}

static sk_sp<SkUnicode> get_unicode() {
    auto factory = SkShapers::BestAvailable();
    return sk_ref_sp<SkUnicode>(factory->getUnicode());
}

}  // namespace

DEF_FUZZ(SkParagraph, fuzz) {
    static sk_sp<ResourceFontCollection> fontCollection = sk_make_sp<ResourceFontCollection>();
    ParagraphStyle paragraph_style = BuildParagraphStyle(fuzz);
    ParagraphBuilderImpl builder(paragraph_style, fontCollection, get_unicode());

    uint8_t iterations;
    fuzz->nextRange(&iterations, 1, MAX_TEXT_ADDITIONS);
    for (int i = 0; i < iterations; i++) {
        AddStyleAndText(&builder, fuzz);
    }
    // TODO(westont): Figure out if we can get more converage by having fontsFound, current
    // they're not.
    // if (!fontCollection->fontsFound()) return;

    builder.pop();
    auto paragraph = builder.Build();

    SkBitmap bm;
    if (!bm.tryAllocN32Pixels(TEST_CANVAS_DIM, TEST_CANVAS_DIM)) {
        return;
    }
    SkCanvas canvas(bm);
    uint8_t layout_width;
    fuzz->next(&layout_width);
    paragraph->layout(layout_width);
    paragraph->paint(&canvas, 0, 0);
}

#endif // SK_ENABLE_PARAGRAPH
