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

#include "tests/Test.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkRect.h"
#include "include/core/SkTileMode.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/Surface.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/shaders/SkImageShader.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/ManagedBackendTexture.h"

namespace skgpu::graphite {

namespace {

using DrawFn = void (*)(sk_sp<SkImage>, SkCanvas*, SkRect /*srcRect*/, SkRect /*dstRect*/);

constexpr SkColor4f kTopColor = SkColors::kRed;
constexpr SkColor4f kBottomColor = SkColors::kBlue;
constexpr int32_t kHalfSize = 4;
constexpr SkISize kImageSize = {2*kHalfSize, 2*kHalfSize};

void test_draw(skiatest::Reporter* reporter,
               Context* context,
               skgpu::Origin origin,
               SkRect srcRect,
               SkRect dstRect,
               DrawFn drawImageFn) {
    std::unique_ptr<Recorder> recorder = context->makeRecorder();

    skgpu::Protected isProtected = skgpu::Protected(context->priv().caps()->protectedSupport());

    SkBitmap bitmap;
    bitmap.allocPixels(SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
                       0);
    bitmap.eraseColor(kTopColor);
    bitmap.erase(kBottomColor,
                 SkIRect::MakeLTRB(0, kHalfSize, kImageSize.width(), kImageSize.height()));

    auto managedTexture =
            sk_gpu_test::ManagedGraphiteTexture::MakeFromPixmap(recorder.get(),
                                                                bitmap.pixmap(),
                                                                skgpu::Mipmapped::kNo,
                                                                skgpu::Renderable::kNo,
                                                                isProtected);

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

    sk_sp<SkImage> image = SkImages::WrapTexture(recorder.get(),
                                                 managedTexture->texture(),
                                                 kRGBA_8888_SkColorType,
                                                 kPremul_SkAlphaType,
                                                 /*colorSpace=*/nullptr,
                                                 origin);

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

    sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(
            recorder.get(),
            SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));

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

    SkCanvas* canvas = surface->getCanvas();

    drawImageFn(image, canvas, srcRect, dstRect);

    SkPixmap pm;

    SkBitmap result;
    result.allocPixels(SkImageInfo::Make(kImageSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
    bool peekPixelsSuccess = result.peekPixels(&pm);
    REPORTER_ASSERT(reporter, peekPixelsSuccess);

    bool readPixelsSuccess = surface->readPixels(pm, 0, 0);
    REPORTER_ASSERT(reporter, readPixelsSuccess);

    bool resultTopColorOnTop = origin == skgpu::Origin::kTopLeft;

    for (int32_t y = 0; y < kImageSize.height(); ++y) {
        for (int32_t x = 0; x < kImageSize.width(); ++x) {
            SkColor4f color = pm.getColor4f(x, y);

            SkColor4f expectedColor = ((y < kHalfSize) == resultTopColorOnTop) ? kTopColor
                                                                               : kBottomColor;
            REPORTER_ASSERT(reporter,
                            color == expectedColor,
                            "At position {%d, %d}, "
                            "expected {%.1f, %.1f, %.1f, %.1f}, "
                            "found {%.1f, %.1f, %.1f, %.1f}",
                            x, y,
                            expectedColor.fR, expectedColor.fG, expectedColor.fB, expectedColor.fA,
                            color.fR, color.fG, color.fB, color.fA);
        }
    }
}

const SkRect kTestSrcRects[] = {
    // entire thing
    SkRect::MakeWH(kImageSize.width(), kImageSize.height()),
    // half rect still splitting top and bottom colors
    SkRect::MakeXYWH(2, 2, kHalfSize, kHalfSize),
};

void test_draw_fn(skiatest::Reporter* reporter,
                  Context* context,
                  DrawFn drawImageFn) {
    for (auto origin : {skgpu::Origin::kTopLeft, skgpu::Origin::kBottomLeft}) {
        for (auto srcRect: kTestSrcRects) {
            test_draw(reporter,
                      context,
                      origin,
                      srcRect,
                      SkRect::MakeWH(kImageSize.width(), kImageSize.height()),
                      drawImageFn);
        }
    }
}

void draw_image(sk_sp<SkImage> image,
                SkCanvas* canvas,
                SkRect srcRect,
                SkRect dstRect) {
    canvas->drawImageRect(image,
                          srcRect,
                          dstRect,
                          SkSamplingOptions(),
                          /*paint=*/nullptr,
                          SkCanvas::kStrict_SrcRectConstraint);
}

void draw_image_with_shader(sk_sp<SkImage> image,
                            SkCanvas* canvas,
                            SkRect srcRect,
                            SkRect dstRect) {
    SkPaint p;
    SkMatrix srcToDst = SkMatrix::RectToRect(srcRect, dstRect);
    p.setShader(SkImageShader::MakeSubset(
                std::move(image),
                srcRect,
                SkTileMode::kClamp,
                SkTileMode::kClamp,
                SkSamplingOptions(),
                &srcToDst));
    canvas->drawRect(dstRect, p);
}

}  // anonymous namespace


DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_drawImage_Graphite, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    test_draw_fn(reporter, context, draw_image);
}

DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageOriginTest_imageShader_Graphite, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    test_draw_fn(reporter, context, draw_image_with_shader);
}

}  // namespace skgpu::graphite
