/*
 * 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 "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkMask.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "tests/Test.h"

#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <optional>

DEF_TEST(SkGlyphRectBasic, reporter) {
    using namespace skglyph;
    SkGlyphRect r{1, 1, 10, 10};
    REPORTER_ASSERT(reporter, !r.empty());
    SkGlyphRect a = rect_union(r, empty_rect());
    REPORTER_ASSERT(reporter, a.rect() == SkRect::MakeLTRB(1, 1, 10, 10));
    auto widthHeight = a.widthHeight();
    REPORTER_ASSERT(reporter, widthHeight.x() == 9 && widthHeight.y() == 9);

    a = rect_intersection(r, full_rect());
    REPORTER_ASSERT(reporter, a.rect() == SkRect::MakeLTRB(1, 1, 10, 10));

    SkGlyphRect acc = full_rect();
    for (int x = -10; x < 10; x++) {
        for(int y = -10; y < 10; y++) {
            acc = rect_intersection(acc, SkGlyphRect(x, y, x + 20, y + 20));
        }
    }
    REPORTER_ASSERT(reporter, acc.rect() == SkRect::MakeLTRB(9, 9, 10, 10));

    acc = empty_rect();
    for (int x = -10; x < 10; x++) {
        for(int y = -10; y < 10; y++) {
            acc = rect_union(acc, SkGlyphRect(x, y, x + 20, y + 20));
        }
    }
    REPORTER_ASSERT(reporter, acc.rect() == SkRect::MakeLTRB(-10, -10, 29, 29));
}

class SkGlyphTestPeer {
public:
    static void SetGlyph1(SkGlyph* glyph) {
        glyph->fAdvanceX = 10;
        glyph->fAdvanceY = 11;
        glyph->fLeft = -1;
        glyph->fTop = -2;
        glyph->fWidth = 8;
        glyph->fHeight = 9;
        glyph->fMaskFormat = SkMask::Format::kA8_Format;
    }

    static void SetGlyph2(SkGlyph* glyph) {
        glyph->fAdvanceX = 10;
        glyph->fAdvanceY = 11;
        glyph->fLeft = 0;
        glyph->fTop = -1;
        glyph->fWidth = 8;
        glyph->fHeight = 9;
        glyph->fMaskFormat = SkMask::Format::kA8_Format;
    }
};

DEF_TEST(SkGlyph_SendMetrics, reporter) {
    {
        SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
        SkGlyphTestPeer::SetGlyph1(&srcGlyph);

        SkBinaryWriteBuffer writeBuffer;
        srcGlyph.flattenMetrics(writeBuffer);

        sk_sp<SkData> data = writeBuffer.snapshotAsData();

        SkReadBuffer readBuffer{data->data(), data->size()};
        std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
        REPORTER_ASSERT(reporter, readBuffer.isValid());
        REPORTER_ASSERT(reporter, dstGlyph.has_value());
        REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
        REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
        REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
    }
    {
        SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
        SkGlyphTestPeer::SetGlyph2(&srcGlyph);

        SkBinaryWriteBuffer writeBuffer;
        srcGlyph.flattenMetrics(writeBuffer);

        sk_sp<SkData> data = writeBuffer.snapshotAsData();

        SkReadBuffer readBuffer{data->data(), data->size()};
        std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
        REPORTER_ASSERT(reporter, readBuffer.isValid());
        REPORTER_ASSERT(reporter, dstGlyph.has_value());
        REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
        REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
        REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());
    }

    uint8_t badData[] = {1, 2, 3, 4, 5, 6, 7, 8};
    SkReadBuffer badBuffer{badData, std::size(badData)};
    std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(badBuffer);
    REPORTER_ASSERT(reporter, !badBuffer.isValid());
    REPORTER_ASSERT(reporter, !dstGlyph.has_value());
}

DEF_TEST(SkGlyph_SendWithImage, reporter) {
    SkArenaAlloc alloc{256};
    SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
    SkGlyphTestPeer::SetGlyph1(&srcGlyph);

    static constexpr uint8_t X = 0xff;
    static constexpr uint8_t O = 0x00;
    uint8_t imageData[][8] = {
        {X,X,X,X,X,X,X,X},
        {X,O,O,O,O,O,O,X},
        {X,O,O,O,O,O,O,X},
        {X,O,O,O,O,O,O,X},
        {X,O,O,X,X,O,O,X},
        {X,O,O,O,O,O,O,X},
        {X,O,O,O,O,O,O,X},
        {X,O,O,O,O,O,O,X},
        {X,X,X,X,X,X,X,X},
    };

    srcGlyph.setImage(&alloc, imageData);

    SkBinaryWriteBuffer writeBuffer;
    srcGlyph.flattenMetrics(writeBuffer);
    srcGlyph.flattenImage(writeBuffer);

    sk_sp<SkData> data = writeBuffer.snapshotAsData();

    SkReadBuffer readBuffer{data->data(), data->size()};
    std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstGlyph.has_value());
    REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
    REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
    REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

    dstGlyph->addImageFromBuffer(readBuffer, &alloc);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    uint8_t* dstImage = (uint8_t*)dstGlyph->image();
    for (int y = 0; y < dstGlyph->height(); ++y) {
        for (int x = 0; x < dstGlyph->width(); ++x) {
            REPORTER_ASSERT(reporter, imageData[y][x] == dstImage[y * dstGlyph->rowBytes() + x]);
        }
    }

    // Add good metrics, but mess up image data
    SkBinaryWriteBuffer badWriteBuffer;
    srcGlyph.flattenMetrics(badWriteBuffer);
    badWriteBuffer.writeInt(7);
    badWriteBuffer.writeInt(8);

    data = badWriteBuffer.snapshotAsData();

    SkReadBuffer badReadBuffer{data->data(), data->size()};
    dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
    REPORTER_ASSERT(reporter, badReadBuffer.isValid());  // Reading glyph metrics is okay.
    REPORTER_ASSERT(reporter, dstGlyph.has_value());
    REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
    REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
    REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

    dstGlyph->addImageFromBuffer(badReadBuffer, &alloc);
    REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
    REPORTER_ASSERT(reporter, !dstGlyph->setImageHasBeenCalled());
}

DEF_TEST(SkGlyph_SendWithPath, reporter) {
    SkArenaAlloc alloc{256};
    SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
    SkGlyphTestPeer::SetGlyph1(&srcGlyph);

    SkPath srcPath;
    srcPath.addRect(srcGlyph.rect());

    srcGlyph.setPath(&alloc, &srcPath, false);

    SkBinaryWriteBuffer writeBuffer;
    srcGlyph.flattenMetrics(writeBuffer);
    srcGlyph.flattenPath(writeBuffer);

    sk_sp<SkData> data = writeBuffer.snapshotAsData();

    SkReadBuffer readBuffer{data->data(), data->size()};
    std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstGlyph.has_value());
    REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
    REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
    REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

    dstGlyph->addPathFromBuffer(readBuffer, &alloc);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstGlyph->setPathHasBeenCalled());
    const SkPath* dstPath = dstGlyph->path();
    REPORTER_ASSERT(reporter, *dstPath == srcPath);

    {
        // Add good metrics, but mess up path data
        SkBinaryWriteBuffer badWriteBuffer;
        srcGlyph.flattenMetrics(badWriteBuffer);
        // Force a false value to be read in addPathFromBuffer for hasPath.
        badWriteBuffer.writeInt(8);
        badWriteBuffer.writeInt(9);

        data = badWriteBuffer.snapshotAsData();

        SkReadBuffer badReadBuffer{data->data(), data->size()};
        dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
        REPORTER_ASSERT(reporter, dstGlyph.has_value());
        REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
        REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
        REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

        dstGlyph->addPathFromBuffer(badReadBuffer, &alloc);
        REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
        REPORTER_ASSERT(reporter, !dstGlyph->setPathHasBeenCalled());
    }
    {
        // Add good metrics, but no path data.
        SkBinaryWriteBuffer badWriteBuffer;
        srcGlyph.flattenMetrics(badWriteBuffer);

        data = badWriteBuffer.snapshotAsData();

        SkReadBuffer badReadBuffer{data->data(), data->size()};
        dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
        REPORTER_ASSERT(reporter, badReadBuffer.isValid());  // Reading glyph metrics is okay.
        REPORTER_ASSERT(reporter, dstGlyph.has_value());
        REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
        REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
        REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

        dstGlyph->addPathFromBuffer(badReadBuffer, &alloc);
        REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
        REPORTER_ASSERT(reporter, !dstGlyph->setPathHasBeenCalled());
    }
}

DEF_TEST(SkGlyph_SendWithDrawable, reporter) {
    SkArenaAlloc alloc{256};
    SkGlyph srcGlyph{SkPackedGlyphID{(SkGlyphID)12}};
    SkGlyphTestPeer::SetGlyph1(&srcGlyph);

    class TestDrawable final : public SkDrawable {
    public:
        TestDrawable(SkRect rect) : fRect(rect) {}
    private:
        const SkRect fRect;
        SkRect onGetBounds() override { return fRect;  }
        size_t onApproximateBytesUsed() override {
            return 0;
        }
        void onDraw(SkCanvas* canvas) override {
            SkPaint paint;
            canvas->drawRect(fRect, paint);
        }
    };

    sk_sp<SkDrawable> srcDrawable = sk_make_sp<TestDrawable>(srcGlyph.rect());
    srcGlyph.setDrawable(&alloc, srcDrawable);
    REPORTER_ASSERT(reporter, srcGlyph.setDrawableHasBeenCalled());

    SkBinaryWriteBuffer writeBuffer;
    srcGlyph.flattenMetrics(writeBuffer);
    srcGlyph.flattenDrawable(writeBuffer);

    sk_sp<SkData> data = writeBuffer.snapshotAsData();

    SkReadBuffer readBuffer{data->data(), data->size()};
    std::optional<SkGlyph> dstGlyph = SkGlyph::MakeFromBuffer(readBuffer);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstGlyph.has_value());
    REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
    REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
    REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

    dstGlyph->addDrawableFromBuffer(readBuffer, &alloc);
    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstGlyph->setDrawableHasBeenCalled());
    SkDrawable* dstDrawable = dstGlyph->drawable();
    REPORTER_ASSERT(reporter, dstDrawable->getBounds() == srcDrawable->getBounds());

    // Add good metrics, but mess up drawable data
    SkBinaryWriteBuffer badWriteBuffer;
    srcGlyph.flattenMetrics(badWriteBuffer);
    badWriteBuffer.writeInt(7);
    badWriteBuffer.writeInt(8);

    data = badWriteBuffer.snapshotAsData();

    SkReadBuffer badReadBuffer{data->data(), data->size()};
    dstGlyph = SkGlyph::MakeFromBuffer(badReadBuffer);
    REPORTER_ASSERT(reporter, badReadBuffer.isValid());  // Reading glyph metrics is okay.
    REPORTER_ASSERT(reporter, dstGlyph.has_value());
    REPORTER_ASSERT(reporter, srcGlyph.advanceVector() == dstGlyph->advanceVector());
    REPORTER_ASSERT(reporter, srcGlyph.rect() == dstGlyph->rect());
    REPORTER_ASSERT(reporter, srcGlyph.maskFormat() == dstGlyph->maskFormat());

    dstGlyph->addDrawableFromBuffer(badReadBuffer, &alloc);
    REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
    REPORTER_ASSERT(reporter, !dstGlyph->setDrawableHasBeenCalled());
}

DEF_TEST(SkPictureBackedGlyphDrawable_Basic, reporter) {
    class TestDrawable final : public SkDrawable {
    public:
        TestDrawable(SkRect rect) : fRect(rect) {}
    private:
        const SkRect fRect;
        SkRect onGetBounds() override { return fRect;  }
        size_t onApproximateBytesUsed() override {
            return 0;
        }
        void onDraw(SkCanvas* canvas) override {
            SkPaint paint;
            canvas->drawRect(fRect, paint);
        }
    };

    sk_sp<SkDrawable> srcDrawable = sk_make_sp<TestDrawable>(SkRect::MakeWH(10, 20));
    SkBinaryWriteBuffer writeBuffer;
    SkPictureBackedGlyphDrawable::FlattenDrawable(writeBuffer, srcDrawable.get());

    sk_sp<SkData> data = writeBuffer.snapshotAsData();

    SkReadBuffer readBuffer{data->data(), data->size()};

    sk_sp<SkPictureBackedGlyphDrawable> dstDrawable =
            SkPictureBackedGlyphDrawable::MakeFromBuffer(readBuffer);

    REPORTER_ASSERT(reporter, readBuffer.isValid());
    REPORTER_ASSERT(reporter, dstDrawable != nullptr);
    REPORTER_ASSERT(reporter, srcDrawable->getBounds() == dstDrawable->getBounds());

    SkBinaryWriteBuffer badWriteBuffer;
    badWriteBuffer.writeInt(7);
    badWriteBuffer.writeInt(8);

    data = badWriteBuffer.snapshotAsData();

    SkReadBuffer badReadBuffer{data->data(), data->size()};

    sk_sp<SkPictureBackedGlyphDrawable> badDrawable =
            SkPictureBackedGlyphDrawable::MakeFromBuffer(badReadBuffer);
    REPORTER_ASSERT(reporter, badDrawable == nullptr);
    REPORTER_ASSERT(reporter, !badReadBuffer.isValid());
}

static sk_sp<SkDrawable> make_sksl_drawable() {
    SkRect rect = SkRect::MakeWH(50, 50);

    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(rect);

    const sk_sp<SkRuntimeEffect> effect =
            SkRuntimeEffect::MakeForShader(
                    SkString("half4 main(float2 xy) { return half4(0, 1, 0, 1); }"))
                    .effect;
    SkASSERT(effect);

    SkPaint paint;
    paint.setShader(effect->makeShader(/*uniforms=*/nullptr, /*children=*/{}));
    // See note in make_nested_sksl_drawable: We include enough ops that this drawable will be
    // preserved as a sub-picture when we wrap it in a second layer.
    for (int i = 0; i < kMaxPictureOpsToUnrollInsteadOfRef + 1; ++i) {
        canvas->drawRect(rect, paint);
    }

    return recorder.finishRecordingAsDrawable();
}

static sk_sp<SkDrawable> make_nested_sksl_drawable() {
    SkRect rect = SkRect::MakeWH(50, 50);

    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(rect);

    auto sksl_drawable = make_sksl_drawable();
    sk_sp<SkPicture> sksl_picture = sksl_drawable->makePictureSnapshot();

    // We need to ensure that the op count of our picture is larger than this threshold, so we
    // actually get a nested (embedded) picture, rather than just playing the ops back.
    SkASSERT(sksl_picture->approximateOpCount() > kMaxPictureOpsToUnrollInsteadOfRef);
    canvas->drawPicture(sksl_picture);

    return recorder.finishRecordingAsDrawable();
}

DEF_TEST(SkPictureBackedGlyphDrawable_SkSL, reporter) {
    for (const sk_sp<SkDrawable>& drawable : {make_sksl_drawable(), make_nested_sksl_drawable()}) {
        for (bool allowSkSL : {true, false}) {
            REPORTER_ASSERT(reporter, drawable);

            SkBinaryWriteBuffer writeBuffer;
            SkPictureBackedGlyphDrawable::FlattenDrawable(writeBuffer, drawable.get());

            sk_sp<SkData> data = writeBuffer.snapshotAsData();

            SkReadBuffer readBuffer{data->data(), data->size()};
            readBuffer.setAllowSkSL(allowSkSL);

            sk_sp<SkPictureBackedGlyphDrawable> dstDrawable =
                    SkPictureBackedGlyphDrawable::MakeFromBuffer(readBuffer);

            REPORTER_ASSERT(reporter, readBuffer.isValid() == allowSkSL);
            REPORTER_ASSERT(reporter, !!dstDrawable == allowSkSL);
        }
    }
}
