/*
 * Copyright 2013 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/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkClipOp.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkPngEncoder.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTDArray.h"
#include "include/utils/SkCanvasStateUtils.h"
#include "src/base/SkTLazy.h"
#include "tests/Test.h"

#include <array>
#include <cstdint>
#include <cstring>

class SkCanvasState;

// Uncomment to include tests of CanvasState across a library boundary. This will change how 'dm'
// is built so that the functions defined in CanvasStateHelpers do not exist inside 'dm', and are
// instead compiled as part of the 'canvas_state_lib' build target. This produces a shared library
// that must be passed to 'dm' using the --library flag when running.
// #define SK_TEST_CANVAS_STATE_CROSS_LIBRARY

// Must be included after SK_TEST_CANVAS_STATE_CROSS_LIBRARY is defined
#include "tests/CanvasStateHelpers.h"

// dlopen, the library flag and canvas state helpers are only used for tests which require this flag
#if defined(SK_TEST_CANVAS_STATE_CROSS_LIBRARY)

static DEFINE_string(library, "",
                     "Support library to use for CanvasState test. Must be provided when"
                     " SK_TEST_CANVAS_STATE_CROSS_LIBRARY to specify the dynamically loaded library"
                     " that receives the captured canvas state. Functions from the library will be"
                     " called to test SkCanvasState. The library is built from the canvas_state_lib"
                     " target");

#include "tools/library/LoadDynamicLibrary.h"

// Automatically loads library passed to --library flag and closes it when it goes out of scope.
class OpenLibResult {
public:
    OpenLibResult(skiatest::Reporter* reporter) {
        if (FLAGS_library.count() == 1) {
            fLibrary = SkLoadDynamicLibrary(FLAGS_library[0]);
            REPORTER_ASSERT(reporter, fLibrary != nullptr, "Failed to open library!");
        } else {
            fLibrary = nullptr;
        }
    }

    ~OpenLibResult() {
        if (fLibrary) {
            SkFreeDynamicLibrary(fLibrary);
        }
    }

    // Load a function address from the library object, or null if the library had failed
    void* procAddress(const char* funcName) {
        if (fLibrary) {
            return SkGetProcedureAddress(fLibrary, funcName);
        }
        return nullptr;
    }

private:
    void* fLibrary;
};

#endif

static void write_image(const SkImage* img, const char path[]) {
    auto data = SkPngEncoder::Encode(nullptr, img, {});
    SkFILEWStream(path).write(data->data(), data->size());
}

static void compare(skiatest::Reporter* reporter, SkImage* img0, SkImage* img1) {
    if ((false)) {
        static int counter;

        SkDebugf("---- counter %d\n", counter);
        SkString name;
        name.printf("no_capture_%d.png", counter);
        write_image(img0, name.c_str());
        name.printf("capture_%d.png", counter);
        write_image(img1, name.c_str());
        counter++;
    }

    SkPixmap pm[2];
    REPORTER_ASSERT(reporter, img0->peekPixels(&pm[0]));
    REPORTER_ASSERT(reporter, img1->peekPixels(&pm[1]));
    // now we memcmp the two bitmaps
    REPORTER_ASSERT(reporter, pm[0].computeByteSize() == pm[1].computeByteSize());
    REPORTER_ASSERT(reporter, pm[0].rowBytes() == (size_t)pm[0].width() * pm[0].info().bytesPerPixel());
    REPORTER_ASSERT(reporter, pm[1].rowBytes() == (size_t)pm[1].width() * pm[1].info().bytesPerPixel());
    if (memcmp(pm[0].addr(0, 0), pm[1].addr(0, 0), pm[0].computeByteSize()) != 0) {
        REPORTER_ASSERT(reporter, false);
    }
}

DEF_TEST(CanvasState_test_complex_layers, reporter) {
    const int WIDTH = 400;
    const int HEIGHT = 400;
    const int SPACER = 10;

    SkRect rect = SkRect::MakeXYWH(SkIntToScalar(SPACER), SkIntToScalar(SPACER),
                                   SkIntToScalar(WIDTH-(2*SPACER)),
                                   SkIntToScalar((HEIGHT-(2*SPACER)) / 7));

    const SkColorType colorTypes[] = {
        kRGB_565_SkColorType, kN32_SkColorType
    };

    const int layerAlpha[] = { 255, 255, 0 };

    bool (*drawFn)(SkCanvasState* state, float l, float t,
                   float r, float b, int32_t s);

#if defined(SK_TEST_CANVAS_STATE_CROSS_LIBRARY)
    OpenLibResult openLibResult(reporter);
    *(void**) (&drawFn) = openLibResult.procAddress("complex_layers_draw_from_canvas_state");
#else
    drawFn = complex_layers_draw_from_canvas_state;
#endif

    REPORTER_ASSERT(reporter, drawFn);
    if (!drawFn) {
        return;
    }

    for (size_t i = 0; i < std::size(colorTypes); ++i) {
        sk_sp<SkImage> images[2];
        for (int j = 0; j < 2; ++j) {
            auto surf = SkSurfaces::Raster(
                    SkImageInfo::Make(WIDTH, HEIGHT, colorTypes[i], kPremul_SkAlphaType));
            SkCanvas* canvas = surf->getCanvas();

            canvas->drawColor(SK_ColorRED);

            for (size_t k = 0; k < std::size(layerAlpha); ++k) {
                SkTLazy<SkPaint> paint;
                if (layerAlpha[k] != 0xFF) {
                    paint.init()->setAlpha(layerAlpha[k]);
                }

                // draw a rect within the layer's bounds and again outside the layer's bounds
                canvas->saveLayer(SkCanvas::SaveLayerRec(&rect, paint.getMaybeNull()));

                if (j) {
                    // Capture from the first Skia.
                    SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(canvas);
                    REPORTER_ASSERT(reporter, state);

                    // And draw to it in the second Skia.
                    bool success = complex_layers_draw_from_canvas_state(state,
                            rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, SPACER);
                    REPORTER_ASSERT(reporter, success);

                    // And release it in the *first* Skia.
                    SkCanvasStateUtils::ReleaseCanvasState(state);
                } else {
                    // Draw in the first Skia.
                    complex_layers_draw(canvas, rect.fLeft, rect.fTop,
                                        rect.fRight, rect.fBottom, SPACER);
                }

                canvas->restore();

                // translate the canvas for the next iteration
                canvas->translate(0, 2*(rect.height() + SPACER));
            }
            images[j] = surf->makeImageSnapshot();
        }

        compare(reporter, images[0].get(), images[1].get());
    }
}

////////////////////////////////////////////////////////////////////////////////

DEF_TEST(CanvasState_test_complex_clips, reporter) {
    const int WIDTH = 400;
    const int HEIGHT = 400;
    const int SPACER = 10;

    SkIRect layerRect = SkIRect::MakeWH(WIDTH, HEIGHT / 4);
    layerRect.inset(2*SPACER, 2*SPACER);

    SkIRect clipRect = layerRect;
    clipRect.fRight = clipRect.fLeft + (clipRect.width() / 2) - (2*SPACER);
    clipRect.outset(SPACER, SPACER);

    SkIRect regionBounds = clipRect;
    regionBounds.offset(clipRect.width() + (2*SPACER), 0);

    SkIRect regionInterior = regionBounds;
    regionInterior.inset(SPACER*3, SPACER*3);

    SkRegion clipRegion;
    clipRegion.setRect(regionBounds);
    clipRegion.op(regionInterior, SkRegion::kDifference_Op);


    const SkRegion::Op clipOps[] = { SkRegion::kIntersect_Op,
                                     SkRegion::kIntersect_Op,
                                     SkRegion::kDifference_Op,
    };

    bool (*drawFn)(SkCanvasState* state, int32_t l, int32_t t,
                   int32_t r, int32_t b, int32_t clipOp,
                   int32_t regionRects, int32_t* rectCoords);

#if defined(SK_TEST_CANVAS_STATE_CROSS_LIBRARY)
    OpenLibResult openLibResult(reporter);
    *(void**) (&drawFn) = openLibResult.procAddress("complex_clips_draw_from_canvas_state");
#else
    drawFn = complex_clips_draw_from_canvas_state;
#endif

    REPORTER_ASSERT(reporter, drawFn);
    if (!drawFn) {
        return;
    }

    sk_sp<SkImage> images[2];
    for (int i = 0; i < 2; ++i) {
        auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(WIDTH, HEIGHT));
        SkCanvas* canvas = surf->getCanvas();

        canvas->drawColor(SK_ColorRED);

        SkRegion localRegion = clipRegion;

        SkPaint paint;
        paint.setAlpha(128);
        for (size_t j = 0; j < std::size(clipOps); ++j) {
            SkRect layerBounds = SkRect::Make(layerRect);
            canvas->saveLayer(SkCanvas::SaveLayerRec(&layerBounds, &paint));

            if (i) {
                SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(canvas);
                REPORTER_ASSERT(reporter, state);

                SkRegion::Iterator iter(localRegion);
                SkTDArray<int32_t> rectCoords;
                for (; !iter.done(); iter.next()) {
                    const SkIRect& rect = iter.rect();
                    *rectCoords.append() = rect.fLeft;
                    *rectCoords.append() = rect.fTop;
                    *rectCoords.append() = rect.fRight;
                    *rectCoords.append() = rect.fBottom;
                }
                bool success = drawFn(state, clipRect.fLeft, clipRect.fTop,
                                      clipRect.fRight, clipRect.fBottom, clipOps[j],
                                      rectCoords.size() / 4, rectCoords.begin());
                REPORTER_ASSERT(reporter, success);

                SkCanvasStateUtils::ReleaseCanvasState(state);
            } else {
                complex_clips_draw(canvas, clipRect.fLeft, clipRect.fTop,
                                   clipRect.fRight, clipRect.fBottom, clipOps[j],
                                   localRegion);
            }

            canvas->restore();

            // translate the canvas and region for the next iteration
            canvas->translate(0, SkIntToScalar(2*(layerRect.height() + (SPACER))));
            localRegion.translate(0, 2*(layerRect.height() + SPACER));
        }
        images[i] = surf->makeImageSnapshot();
    }

    compare(reporter, images[0].get(), images[1].get());
}

////////////////////////////////////////////////////////////////////////////////

DEF_TEST(CanvasState_test_soft_clips, reporter) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(10, 10);
    SkCanvas canvas(bitmap);

    SkRRect roundRect;
    roundRect.setOval(SkRect::MakeWH(5, 5));

    canvas.clipRRect(roundRect, SkClipOp::kIntersect, true);

    SkCanvasState* state = SkCanvasStateUtils::CaptureCanvasState(&canvas);
    REPORTER_ASSERT(reporter, !state);
}

DEF_TEST(CanvasState_test_saveLayer_clip, reporter) {
    const int WIDTH = 100;
    const int HEIGHT = 100;
    const int LAYER_WIDTH = 50;
    const int LAYER_HEIGHT = 50;

    SkBitmap bitmap;
    bitmap.allocN32Pixels(WIDTH, HEIGHT);
    SkCanvas canvas(bitmap);

    SkRect bounds = SkRect::MakeWH(SkIntToScalar(LAYER_WIDTH), SkIntToScalar(LAYER_HEIGHT));
    canvas.clipRect(SkRect::MakeWH(SkIntToScalar(WIDTH), SkIntToScalar(HEIGHT)));

    // Check that saveLayer sets the clip stack to the layer bounds.
    canvas.saveLayer(&bounds, nullptr);
    SkIRect devClip = canvas.getDeviceClipBounds();
    REPORTER_ASSERT(reporter, canvas.isClipRect());
    REPORTER_ASSERT(reporter, devClip.width() == LAYER_WIDTH);
    REPORTER_ASSERT(reporter, devClip.height() == LAYER_HEIGHT);
    canvas.restore();
}
