/*
 * 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 "src/ports/SkOSLibrary.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();
}
