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

#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkImageFilters.h"
#include "src/core/SkRecord.h"
#include "src/core/SkRecordCanvas.h"
#include "src/core/SkRecordOpts.h"
#include "src/core/SkRecords.h"
#include "tests/RecordTestUtils.h"
#include "tests/Test.h"

#include <array>
#include <cstddef>

static const int W = 1920, H = 1080;

DEF_TEST(RecordOpts_NoopDraw, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    recorder.drawRect(SkRect::MakeWH(200, 200), SkPaint());
    recorder.drawRect(SkRect::MakeWH(300, 300), SkPaint());
    recorder.drawRect(SkRect::MakeWH(100, 100), SkPaint());

    record.replace<SkRecords::NoOp>(1);  // NoOps should be allowed.

    SkRecordNoopSaveRestores(&record);

    REPORTER_ASSERT(r, 2 == count_instances_of_type<SkRecords::DrawRect>(record));
}

DEF_TEST(RecordOpts_SingleNoopSaveRestore, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    recorder.save();
        recorder.clipRect(SkRect::MakeWH(200, 200));
    recorder.restore();

    SkRecordNoopSaveRestores(&record);
    for (int i = 0; i < 3; i++) {
        assert_type<SkRecords::NoOp>(r, record, i);
    }
}

DEF_TEST(RecordOpts_NoopSaveRestores, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    // The second pass will clean up this pair after the first pass noops all the innards.
    recorder.save();
        // A simple pointless pair of save/restore.
        recorder.save();
        recorder.restore();

        // As long as we don't draw in there, everything is a noop.
        recorder.save();
            recorder.clipRect(SkRect::MakeWH(200, 200));
            recorder.clipRect(SkRect::MakeWH(100, 100));
        recorder.restore();
    recorder.restore();

    SkRecordNoopSaveRestores(&record);
    for (int index = 0; index < record.count(); index++) {
        assert_type<SkRecords::NoOp>(r, record, index);
    }
}

DEF_TEST(RecordOpts_SaveSaveLayerRestoreRestore, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    // A previous bug NoOp'd away the first 3 commands.
    recorder.save();
        recorder.saveLayer(nullptr, nullptr);
        recorder.restore();
    recorder.restore();

    SkRecordNoopSaveRestores(&record);
    switch (record.count()) {
        case 4:
            assert_type<SkRecords::Save>     (r, record, 0);
            assert_type<SkRecords::SaveLayer>(r, record, 1);
            assert_type<SkRecords::Restore>  (r, record, 2);
            assert_type<SkRecords::Restore>  (r, record, 3);
            break;
        case 2:
            assert_type<SkRecords::SaveLayer>(r, record, 0);
            assert_type<SkRecords::Restore>  (r, record, 1);
            break;
        case 0:
            break;
        default:
            REPORTER_ASSERT(r, false);
    }
}

#ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
static void assert_savelayer_restore(skiatest::Reporter* r,
                                     SkRecord* record,
                                     int i,
                                     bool shouldBeNoOped) {
    SkRecordNoopSaveLayerDrawRestores(record);
    if (shouldBeNoOped) {
        assert_type<SkRecords::NoOp>(r, *record, i);
        assert_type<SkRecords::NoOp>(r, *record, i+1);
    } else {
        assert_type<SkRecords::SaveLayer>(r, *record, i);
        assert_type<SkRecords::Restore>(r, *record, i+1);
    }
}

static void assert_savelayer_draw_restore(skiatest::Reporter* r,
                                          SkRecord* record,
                                          int i,
                                          bool shouldBeNoOped) {
    SkRecordNoopSaveLayerDrawRestores(record);
    if (shouldBeNoOped) {
        assert_type<SkRecords::NoOp>(r, *record, i);
        assert_type<SkRecords::NoOp>(r, *record, i+2);
    } else {
        assert_type<SkRecords::SaveLayer>(r, *record, i);
        assert_type<SkRecords::Restore>(r, *record, i+2);
    }
}

DEF_TEST(RecordOpts_NoopSaveLayerDrawRestore, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    SkRect bounds = SkRect::MakeWH(100, 200);
    SkRect   draw = SkRect::MakeWH(50, 60);

    SkPaint alphaOnlyLayerPaint, translucentLayerPaint, xfermodeLayerPaint;
    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
    xfermodeLayerPaint.setBlendMode(SkBlendMode::kDstIn);  // Any effect will do.

    SkPaint opaqueDrawPaint, translucentDrawPaint;
    opaqueDrawPaint.setColor(0xFF020202);  // Opaque.
    translucentDrawPaint.setColor(0x0F020202);  // Not opaque.

    // SaveLayer/Restore removed: No paint = no point.
    recorder.saveLayer(nullptr, nullptr);
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 0, true);

    // Bounds don't matter.
    recorder.saveLayer(&bounds, nullptr);
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 3, true);

    // TODO(mtklein): test case with null draw paint

    // No change: layer paint isn't alpha-only.
    recorder.saveLayer(nullptr, &translucentLayerPaint);
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 6, false);

    // No change: layer paint has an effect.
    recorder.saveLayer(nullptr, &xfermodeLayerPaint);
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 9, false);

    // SaveLayer/Restore removed: we can fold in the alpha!
    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
        recorder.drawRect(draw, translucentDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 12, true);

    // SaveLayer/Restore removed: we can fold in the alpha!
    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 15, true);

    const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, record, 16);
    REPORTER_ASSERT(r, drawRect != nullptr);
    REPORTER_ASSERT(r, drawRect->paint.getColor() == 0x03020202);

    // saveLayer w/ backdrop should NOT go away
    sk_sp<SkImageFilter> filter(SkImageFilters::Blur(3, 3, nullptr));
    recorder.saveLayer({ nullptr, nullptr, filter.get(), 0});
        recorder.drawRect(draw, opaqueDrawPaint);
    recorder.restore();
    assert_savelayer_draw_restore(r, &record, 18, false);
}
#endif

static void assert_merge_svg_opacity_and_filter_layers(skiatest::Reporter* r,
                                                       SkRecord* record,
                                                       int i,
                                                       bool shouldBeNoOped) {
    SkRecordMergeSvgOpacityAndFilterLayers(record);
    if (shouldBeNoOped) {
        assert_type<SkRecords::NoOp>(r, *record, i);
        assert_type<SkRecords::NoOp>(r, *record, i + 6);
    } else {
        assert_type<SkRecords::SaveLayer>(r, *record, i);
        assert_type<SkRecords::Restore>(r, *record, i + 6);
    }
}

DEF_TEST(RecordOpts_MergeSvgOpacityAndFilterLayers, r) {
    SkRecord record;
    SkRecordCanvas recorder(&record, W, H);

    SkRect bounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(200));
    SkRect clip = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(60));

    SkPaint alphaOnlyLayerPaint;
    alphaOnlyLayerPaint.setColor(0x03000000);  // Only alpha.
    SkPaint translucentLayerPaint;
    translucentLayerPaint.setColor(0x03040506);  // Not only alpha.
    SkPaint xfermodePaint;
    xfermodePaint.setBlendMode(SkBlendMode::kDstIn);
    SkPaint colorFilterPaint;
    colorFilterPaint.setColorFilter(
        SkColorFilters::Blend(SK_ColorLTGRAY, SkBlendMode::kSrcIn));

    SkPaint opaqueFilterLayerPaint;
    opaqueFilterLayerPaint.setColor(0xFF020202);  // Opaque.
    SkPaint translucentFilterLayerPaint;
    translucentFilterLayerPaint.setColor(0x0F020202);  // Not opaque.
    sk_sp<SkPicture> shape;
    {
        SkPictureRecorder picRecorder;
        SkCanvas* canvas = picRecorder.beginRecording(SkIntToScalar(100), SkIntToScalar(100));
        SkPaint shapePaint;
        shapePaint.setColor(SK_ColorWHITE);
        canvas->drawRect(SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50)), shapePaint);
        shape = picRecorder.finishRecordingAsPicture();
    }
    translucentFilterLayerPaint.setImageFilter(SkImageFilters::Picture(shape));

    int index = 0;

    {
        sk_sp<SkImageFilter> filter(SkImageFilters::Blur(3, 3, nullptr));
        // first (null) should be optimized, 2nd should not
        SkImageFilter* filters[] = { nullptr, filter.get() };

        // Any combination of these should cause the pattern to be optimized.
        SkRect* firstBounds[] = { nullptr, &bounds };
        SkPaint* firstPaints[] = { nullptr, &alphaOnlyLayerPaint };
        SkRect* secondBounds[] = { nullptr, &bounds };
        SkPaint* secondPaints[] = { &opaqueFilterLayerPaint, &translucentFilterLayerPaint };

        for (auto outerF : filters) {
            bool outerNoOped = !outerF;
            for (auto innerF : filters) {
                for (size_t i = 0; i < std::size(firstBounds); ++ i) {
                    for (size_t j = 0; j < std::size(firstPaints); ++j) {
                        for (size_t k = 0; k < std::size(secondBounds); ++k) {
                            for (size_t m = 0; m < std::size(secondPaints); ++m) {
                                bool innerNoOped = !secondBounds[k] && !secondPaints[m] && !innerF;

                                recorder.saveLayer({firstBounds[i], firstPaints[j], outerF, 0});
                                recorder.save();
                                recorder.clipRect(clip);
                                recorder.saveLayer({secondBounds[k], secondPaints[m], innerF, 0});
                                recorder.restore();
                                recorder.restore();
                                recorder.restore();
                                assert_merge_svg_opacity_and_filter_layers(r, &record, index,
                                                                           outerNoOped);
                            #ifndef SK_BUILD_FOR_ANDROID_FRAMEWORK
                                assert_savelayer_restore(r, &record, index + 3, innerNoOped);
                            #endif
                                index += 7;
                            }
                        }
                    }
                }
            }
        }
    }

    // These should cause the pattern to stay unoptimized:
    struct {
        SkPaint* firstPaint;
        SkPaint* secondPaint;
    } noChangeTests[] = {
        // No change: nullptr filter layer paint not implemented.
        { &alphaOnlyLayerPaint, nullptr },
        // No change: layer paint is not alpha-only.
        { &translucentLayerPaint, &opaqueFilterLayerPaint },
        // No change: layer paint has an xfereffect.
        { &xfermodePaint, &opaqueFilterLayerPaint },
        // No change: filter layer paint has an xfereffect.
        { &alphaOnlyLayerPaint, &xfermodePaint },
        // No change: layer paint has a color filter.
        { &colorFilterPaint, &opaqueFilterLayerPaint },
        // No change: filter layer paint has a color filter (until the optimization accounts for
        // constant color draws that can filter the color).
        { &alphaOnlyLayerPaint, &colorFilterPaint }
    };

    for (size_t i = 0; i < std::size(noChangeTests); ++i) {
        recorder.saveLayer(nullptr, noChangeTests[i].firstPaint);
        recorder.save();
        recorder.clipRect(clip);
        recorder.saveLayer(nullptr, noChangeTests[i].secondPaint);
        recorder.restore();
        recorder.restore();
        recorder.restore();
        assert_merge_svg_opacity_and_filter_layers(r, &record, index, false);
        index += 7;
    }

    // Test the folded alpha value.
    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
    recorder.save();
    recorder.clipRect(clip);
    recorder.saveLayer(nullptr, &opaqueFilterLayerPaint);
    recorder.restore();
    recorder.restore();
    recorder.restore();
    assert_merge_svg_opacity_and_filter_layers(r, &record, index, true);

    const SkRecords::SaveLayer* saveLayer = assert_type<SkRecords::SaveLayer>(r, record, index + 3);
    REPORTER_ASSERT(r, saveLayer != nullptr);
    REPORTER_ASSERT(r, saveLayer->paint->getColor() == 0x03020202);

    index += 7;

    // Test that currently we do not fold alphas for patterns without the clip. This is just not
    // implemented.
    recorder.saveLayer(nullptr, &alphaOnlyLayerPaint);
    recorder.saveLayer(nullptr, &opaqueFilterLayerPaint);
    recorder.restore();
    recorder.restore();
    SkRecordMergeSvgOpacityAndFilterLayers(&record);
    assert_type<SkRecords::SaveLayer>(r, record, index);
    assert_type<SkRecords::SaveLayer>(r, record, index + 1);
    assert_type<SkRecords::Restore>(r, record, index + 2);
    assert_type<SkRecords::Restore>(r, record, index + 3);
    index += 4;
}

static void do_draw(SkCanvas* canvas, SkColor color, bool doLayer) {
    canvas->drawColor(SK_ColorWHITE);

    SkPaint p;
    p.setColor(color);

    if (doLayer) {
        canvas->saveLayer(nullptr, nullptr);
        p.setBlendMode(SkBlendMode::kSrc);
        canvas->drawPaint(p);
        canvas->restore();
    } else {
        canvas->drawPaint(p);
    }
}

static bool is_equal(SkSurface* a, SkSurface* b) {
    const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
    SkPMColor ca, cb;
    a->readPixels(info, &ca, sizeof(SkPMColor), 0, 0);
    b->readPixels(info, &cb, sizeof(SkPMColor), 0, 0);
    return ca == cb;
}

// Test drawing w/ and w/o a simple layer (no bounds or paint), so see that drawing ops
// that *should* draw the same in fact do.
//
// Perform this test twice : once directly, and once via a picture
//
static void do_savelayer_srcmode(skiatest::Reporter* r, SkColor color) {
    for (int doPicture = 0; doPicture <= 1; ++doPicture) {
        sk_sp<SkSurface> surf0 = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(10, 10));
        sk_sp<SkSurface> surf1 = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(10, 10));
        SkCanvas* c0 = surf0->getCanvas();
        SkCanvas* c1 = surf1->getCanvas();

        SkPictureRecorder rec0, rec1;
        if (doPicture) {
            c0 = rec0.beginRecording(10, 10);
            c1 = rec1.beginRecording(10, 10);
        }

        do_draw(c0, color, false);
        do_draw(c1, color, true);

        if (doPicture) {
            surf0->getCanvas()->drawPicture(rec0.finishRecordingAsPicture());
            surf1->getCanvas()->drawPicture(rec1.finishRecordingAsPicture());
        }

        // we replicate the assert so we can see which line is reported if there is a failure
        if (doPicture) {
            REPORTER_ASSERT(r, is_equal(surf0.get(), surf1.get()));
        } else {
            REPORTER_ASSERT(r, is_equal(surf0.get(), surf1.get()));
        }
    }
}

DEF_TEST(savelayer_srcmode_opaque, r) {
    do_savelayer_srcmode(r, SK_ColorRED);
}

DEF_TEST(savelayer_srcmode_alpha, r) {
    do_savelayer_srcmode(r, 0x80FF0000);
}

