/*
 * Copyright 2020 Google Inc.
 *
 * 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/SkEncodedImageFormat.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkImageEncoder.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/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 "src/core/SkOSFile.h"
#include "src/core/SkSpan.h"
#include "src/utils/SkOSPath.h"
#include "src/utils/SkShaperJSONWriter.h"
#include "tests/Test.h"
#include "tools/Resources.h"


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

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;
        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(SkTypeface::MakeFromFile(file_path.c_str()));
        }

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

}  // namespace

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

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