/*
 * Copyright 2022 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/SkColorSpace.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"

static void check_pixels(skiatest::Reporter* reporter, const SkBitmap& bitmap,
                         GrSurfaceOrigin origin) {
    const uint32_t* canvasPixels = static_cast<const uint32_t*>(bitmap.getPixels());

    bool failureFound = false;
    bool foundNonBlue = false;

    for (int cy = 0; cy < 8 && !failureFound; ++cy) {
        int cx = 4; // Just need to check one column;
        SkPMColor canvasPixel = canvasPixels[cy * 8 + cx];
        // We don't know which way the GPU will snap so the non-blue line could either be at row
        // 3 or 4 since we drew the line at a y value of 4. We check that one of those two values
        // is green and all the rest are blue. The key thing is that we should not get any red
        // values since the green line in the saveLayer should snap the same way and overwrite the
        // red line.
        if (cy == 3) {
            if (canvasPixel != 0xFFFF0000 && canvasPixel != 0xFF00FF00) {
                failureFound = true;
                ERRORF(reporter, "Wrong color at %d, %d. Got 0x%08x when we expected Blue or Green."
                       " Origin is: %s",
                       cx, cy, canvasPixel, GrSurfaceOriginToStr(origin));
            }
            if (canvasPixel != 0XFFFF0000) {
                foundNonBlue = true;
            }
        } else {
            SkPMColor expectedPixel;
            if (cy == 4 && !foundNonBlue) {
                expectedPixel = 0xFF00FF00; // Green
            } else {
                expectedPixel = 0xFFFF0000; // Blue
            }
            if (canvasPixel != expectedPixel) {
                failureFound = true;
                ERRORF(reporter,
                       "Wrong color at %d, %d. Got 0x%08x when we expected 0x%08x. Origin is: %s",
                       cx, cy, canvasPixel, expectedPixel, GrSurfaceOriginToStr(origin));
            }
        }
    }
}

static void run_test(skiatest::Reporter* reporter,
                     GrDirectContext* context,
                     GrSurfaceOrigin origin) {
    auto beTexture = context->createBackendTexture(8, 8, kRGBA_8888_SkColorType, GrMipmapped::kNo,
                                                   GrRenderable::kYes, GrProtected::kNo);
    REPORTER_ASSERT(reporter, beTexture.isValid());
    if (!beTexture.isValid()) {
        return;
    }

    auto surface = SkSurface::MakeFromBackendTexture(context, beTexture, origin, 0,
                                                     kRGBA_8888_SkColorType, nullptr, nullptr);
    REPORTER_ASSERT(reporter, surface);
    if (!surface) {
        return;
    }

    SkCanvas* canvas = surface->getCanvas();

    canvas->clear(SK_ColorBLUE);

    SkPaint paint;
    paint.setColor(SK_ColorRED);
    canvas->drawLine({ 0,4 }, { 8,4 }, paint);

    SkRect bounds = SkRect::MakeWH(8, 8);
    SkPaint layerPaint;
    canvas->saveLayer(bounds, &paint);
    paint.setColor(SK_ColorGREEN);
    canvas->drawLine({ 0,4 }, { 8,4 }, paint);
    canvas->restore();

    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
    surface->readPixels(bitmap, 0, 0);

    check_pixels(reporter, bitmap, origin);

    context->deleteBackendTexture(beTexture);
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SaveLayerOrigin, reporter, context_info) {
    GrDirectContext* context = context_info.directContext();
    run_test(reporter, context, kBottomLeft_GrSurfaceOrigin);
    run_test(reporter, context, kTopLeft_GrSurfaceOrigin);
}
