/*
 * Copyright 2019 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/SkImage.h"
#include "include/core/SkSurface.h"
#include "src/core/SkAutoPixmapStorage.h"

#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"

static constexpr int kSize = 32;

static SkColor4f get_trans_black_expected_color(SkColorChannelFlag channels) {
    float a = 0;
    if (!(channels & kAlpha_SkColorChannelFlag)) {
        a = 1;
    }

    return { 0, 0, 0, a };
}

static SkColor4f get_opaque_white_expected_color(SkColorChannelFlag channels) {
    if (channels & kGray_SkColorChannelFlag) {
        return { 1, 1, 1, 1 };
    }

    float r = 1, g = 1, b = 1;
    if (!(channels & kRed_SkColorChannelFlag)) {
        r = 0;
    }
    if (!(channels & kGreen_SkColorChannelFlag)) {
        g = 0;
    }
    if (!(channels & kBlue_SkColorChannelFlag)) {
        b = 0;
    }

    return { r, g, b, 1.0f };
}

struct TestCase {
    SkColorType        fColorType;
    SkAlphaType        fAlphaType;
    SkColorChannelFlag fChannels;
    bool               fGpuCanMakeSurfaces;
    bool               fCpuCanMakeSurfaces;
};

static const TestCase gTests[] = {
    { kAlpha_8_SkColorType,     kPremul_SkAlphaType, kAlpha_SkColorChannelFlag, true,  true },
    { kA16_unorm_SkColorType,   kPremul_SkAlphaType, kAlpha_SkColorChannelFlag, false, false},
    { kA16_float_SkColorType,   kPremul_SkAlphaType, kAlpha_SkColorChannelFlag, false, false},
    { kRGB_565_SkColorType,     kOpaque_SkAlphaType, kRGB_SkColorChannelFlags,  true,  true },
    { kARGB_4444_SkColorType,   kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGBA_8888_SkColorType,   kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGB_888x_SkColorType,    kOpaque_SkAlphaType, kRGB_SkColorChannelFlags,  true,  true },
    { kBGRA_8888_SkColorType,   kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGBA_1010102_SkColorType,kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGB_101010x_SkColorType, kOpaque_SkAlphaType, kRGB_SkColorChannelFlags,  true,  true },
    { kGray_8_SkColorType,      kOpaque_SkAlphaType, kGray_SkColorChannelFlag,  true,  true },
    { kRGBA_F16Norm_SkColorType,kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGBA_F16_SkColorType,    kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kRGBA_F32_SkColorType,    kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, true,  true },
    { kR8G8_unorm_SkColorType,  kOpaque_SkAlphaType, kRG_SkColorChannelFlags,   true,  false},
    { kR16G16_unorm_SkColorType,kOpaque_SkAlphaType, kRG_SkColorChannelFlags,   false, false},
    { kR16G16_float_SkColorType,kOpaque_SkAlphaType, kRG_SkColorChannelFlags,   false, false},
    { kR16G16B16A16_unorm_SkColorType,
                                kPremul_SkAlphaType, kRGBA_SkColorChannelFlags, false, false},
};

static void raster_tests(skiatest::Reporter* reporter, const TestCase& test) {

    const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
    const SkImageInfo f32Unpremul = SkImageInfo::Make(kSize, kSize, kRGBA_F32_SkColorType,
                                                      kUnpremul_SkAlphaType);

    uint32_t actualChannels = SkColorTypeChannelFlags(test.fColorType);
    REPORTER_ASSERT(reporter, test.fChannels == actualChannels);

    // Not all colorTypes can be drawn to
    {
        auto s = SkSurface::MakeRaster(nativeII);
        REPORTER_ASSERT(reporter, SkToBool(s) == test.fCpuCanMakeSurfaces);
    }

    // opaque formats should make transparent black become opaque
    {
        SkAutoPixmapStorage pm;
        pm.alloc(nativeII);
        pm.erase(SkColors::kTransparent);
        SkColor actual = pm.getColor(0, 0);
        SkColor4f expected = get_trans_black_expected_color(test.fChannels);
        REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
    }

    // unused channels should drop out
    {
        SkAutoPixmapStorage pm;
        pm.alloc(nativeII);
        pm.erase(SkColors::kWhite);
        SkColor actual = pm.getColor(0, 0);
        SkColor4f expected = get_opaque_white_expected_color(test.fChannels);
        REPORTER_ASSERT(reporter, expected.toSkColor() == actual);
    }

    // Reading back from an image to the same colorType should always work
    {
        SkAutoPixmapStorage srcPM;
        srcPM.alloc(nativeII);
        srcPM.erase(SkColors::kWhite);
        auto i = SkImage::MakeFromRaster(srcPM, nullptr, nullptr);
        REPORTER_ASSERT(reporter, SkToBool(i));

        SkAutoPixmapStorage readbackPM;
        readbackPM.alloc(nativeII);
        readbackPM.erase(SkColors::kTransparent);

        REPORTER_ASSERT(reporter, i->readPixels(readbackPM, 0, 0));

        SkColor expected = srcPM.getColor(0, 0);
        SkColor actual = readbackPM.getColor(0, 0);
        REPORTER_ASSERT(reporter, expected == actual);
    }

    // Rendering to an F32 surface should always work
    {
        SkAutoPixmapStorage srcPM;
        srcPM.alloc(nativeII);
        srcPM.erase(SkColors::kWhite);
        auto i = SkImage::MakeFromRaster(srcPM, nullptr, nullptr);
        REPORTER_ASSERT(reporter, SkToBool(i));

        auto s = SkSurface::MakeRaster(f32Unpremul);
        REPORTER_ASSERT(reporter, SkToBool(s));

        {
            auto c = s->getCanvas();
            c->drawImage(i, 0, 0);
        }

        SkAutoPixmapStorage readbackPM;
        readbackPM.alloc(f32Unpremul);
        readbackPM.erase(SkColors::kTransparent);

        REPORTER_ASSERT(reporter, i->readPixels(readbackPM, 0, 0));

        SkColor expected = srcPM.getColor(0, 0);
        SkColor actual = readbackPM.getColor(0, 0);
        REPORTER_ASSERT(reporter, expected == actual);
    }
}

static void compare_pixmaps(skiatest::Reporter* reporter,
                            const SkPixmap& expected, const SkPixmap& actual,
                            SkColorType ct, const char* label) {
    const float tols[4] = {0.0f, 0.0f, 0.0f, 0};

    auto error = std::function<ComparePixmapsErrorReporter>(
        [reporter, ct, label](int x, int y, const float diffs[4]) {
            SkASSERT(x >= 0 && y >= 0);
            ERRORF(reporter, "%s %s - mismatch at %d, %d (%f, %f, %f %f)",
                   ToolUtils::colortype_name(ct), label, x, y,
                   diffs[0], diffs[1], diffs[2], diffs[3]);
        });

    ComparePixels(expected, actual, tols, error);
}

static void gpu_tests(GrContext* context, skiatest::Reporter* reporter, const TestCase& test) {

    const SkImageInfo nativeII = SkImageInfo::Make(kSize, kSize, test.fColorType, test.fAlphaType);
    const SkImageInfo f32Unpremul = SkImageInfo::Make(kSize, kSize, kRGBA_F32_SkColorType,
                                                      kUnpremul_SkAlphaType);

    // We had better not be able to render to prohibited colorTypes
    if (!test.fGpuCanMakeSurfaces) {
        auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, nativeII);
        REPORTER_ASSERT(reporter, !SkToBool(s));
    }

    if (!context->colorTypeSupportedAsImage(test.fColorType)) {
        return;
    }

    SkAutoPixmapStorage nativeExpected;
    nativeExpected.alloc(nativeII);
    nativeExpected.erase(SkColors::kWhite);

    for (bool fullInit : { false, true }) {
        GrBackendTexture backendTex;

        bool finishedBECreate = false;
        auto markFinished = [](void* context) {
            *(bool*)context = true;
        };
        if (fullInit) {
            backendTex = context->createBackendTexture(&nativeExpected, 1,
                                                       GrRenderable::kNo, GrProtected::kNo,
                                                       markFinished, &finishedBECreate);
        } else {
            backendTex = context->createBackendTexture(kSize, kSize, test.fColorType,
                                                       SkColors::kWhite, GrMipMapped::kNo,
                                                       GrRenderable::kNo, GrProtected::kNo,
                                                       markFinished, &finishedBECreate);
        }
        REPORTER_ASSERT(reporter, backendTex.isValid());
        context->submit();
        while (backendTex.isValid() && !finishedBECreate) {
            context->checkAsyncWorkCompletion();
        }

        auto img = SkImage::MakeFromTexture(context, backendTex, kTopLeft_GrSurfaceOrigin,
                                            test.fColorType, test.fAlphaType, nullptr);
        REPORTER_ASSERT(reporter, SkToBool(img));

        {
            SkAutoPixmapStorage nativeActual;
            nativeActual.alloc(nativeII);
            nativeActual.erase(SkColors::kTransparent);

            if (img->readPixels(nativeActual, 0, 0)) {
                compare_pixmaps(reporter, nativeExpected, nativeActual,
                                test.fColorType, "SkImage::readPixels to native CT");
            }

            // SkSurface::readPixels with the same colorType as the source pixels round trips
            // (when allowed)
            if (context->colorTypeSupportedAsSurface(test.fColorType)) {
                auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, nativeII);
                REPORTER_ASSERT(reporter, SkToBool(s));

                {
                    SkCanvas* c = s->getCanvas();
                    c->drawImage(img, 0, 0);
                }

                nativeActual.erase(SkColors::kTransparent);
                REPORTER_ASSERT(reporter, s->readPixels(nativeActual, 0, 0));

                compare_pixmaps(reporter, nativeExpected, nativeActual,
                                test.fColorType, "SkSurface::readPixels to native CT");
            }
        }

        {
            SkAutoPixmapStorage f32Expected;
            f32Expected.alloc(f32Unpremul);
            f32Expected.erase(get_opaque_white_expected_color(test.fChannels));

            // read back to F32 if possible
            {
                SkAutoPixmapStorage f32Actual;
                f32Actual.alloc(f32Unpremul);
                f32Actual.erase(SkColors::kTransparent);
                if (img->readPixels(f32Actual, 0, 0)) {
                    compare_pixmaps(reporter, f32Expected, f32Actual,
                                    test.fColorType, "SkImage::readPixels to F32");
                }
            }

            // drawing a native SkImage works appropriately (as assessed by reading back from an
            // RGBA8 surface to an F32 pixmap)
            {
                const SkImageInfo rgba8888Premul = SkImageInfo::Make(kSize, kSize,
                                                                     kRGBA_8888_SkColorType,
                                                                     kPremul_SkAlphaType);

                auto s = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, rgba8888Premul);
                REPORTER_ASSERT(reporter, SkToBool(s));

                {
                    SkCanvas* c = s->getCanvas();
                    c->drawImage(img, 0, 0);
                }

                SkAutoPixmapStorage f32Actual;
                f32Actual.alloc(f32Unpremul);
                f32Actual.erase(SkColors::kTransparent);
                REPORTER_ASSERT(reporter, s->readPixels(f32Actual, 0, 0));

                compare_pixmaps(reporter, f32Expected, f32Actual,
                                test.fColorType, "SkSurface::drawn to RGBA8888");
            }
        }

        img.reset();
        context->flushAndSubmit();
        context->deleteBackendTexture(backendTex);
    }
}

DEF_TEST(ExtendedSkColorTypeTests_raster, reporter) {
    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
        raster_tests(reporter, gTests[i]);
    }
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ExtendedSkColorTypeTests_gpu, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();

    for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) {
        gpu_tests(context, reporter, gTests[i]);
    }
}
