/*
 * 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/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(SkColorTypeComponentFlag components) {
    float a = 0;
    if (!(components & kAlpha_SkColorTypeComponentFlag)) {
        a = 1;
    }

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

static SkColor4f get_opaque_white_expected_color(SkColorTypeComponentFlag components) {

    if (components & kGray_SkColorTypeComponentFlag) {
        return { 1, 1, 1, 1 };
    }

    float r = 1, g = 1, b = 1;
    if (!(components & kRed_SkColorTypeComponentFlag)) {
        r = 0;
    }
    if (!(components & kGreen_SkColorTypeComponentFlag)) {
        g = 0;
    }
    if (!(components & kBlue_SkColorTypeComponentFlag)) {
        b = 0;
    }

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

struct TestCase {
    SkColorType              fColorType;
    SkAlphaType              fAlphaType;
    SkColorTypeComponentFlag fComponents;
    bool                     fCanMakeSurfaces;
};

static const TestCase gTests[] = {
    { kAlpha_8_SkColorType,           kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, true  },
    { kA16_unorm_SkColorType,         kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, false },
    { kA16_float_SkColorType,         kPremul_SkAlphaType, kAlpha_SkColorTypeComponentFlag, false },
    { kRGB_565_SkColorType,           kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags,  true  },
    { kARGB_4444_SkColorType,         kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGBA_8888_SkColorType,         kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGB_888x_SkColorType,          kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags,  true  },
    { kBGRA_8888_SkColorType,         kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGBA_1010102_SkColorType,      kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGB_101010x_SkColorType,       kOpaque_SkAlphaType, kRGB_SkColorTypeComponentFlags,  true  },
    { kGray_8_SkColorType,            kOpaque_SkAlphaType, kGray_SkColorTypeComponentFlag,  true  },
    { kRGBA_F16Norm_SkColorType,      kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGBA_F16_SkColorType,          kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kRGBA_F32_SkColorType,          kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, true  },
    { kR8G8_unorm_SkColorType,        kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false },
    { kR16G16_unorm_SkColorType,      kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false },
    { kR16G16_float_SkColorType,      kOpaque_SkAlphaType, kRG_SkColorTypeComponentFlags,   false },
    { kR16G16B16A16_unorm_SkColorType,kPremul_SkAlphaType, kRGBA_SkColorTypeComponentFlags, 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 actualComponents = SkColorTypeComponentFlags(test.fColorType);
    REPORTER_ASSERT(reporter, test.fComponents == actualComponents);

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

    // 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.fComponents);
        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.fComponents);
        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]);
        });

    compare_pixels(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.fCanMakeSurfaces) {
        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;

        if (fullInit) {
            backendTex = context->createBackendTexture(&nativeExpected, 1,
                                                       GrRenderable::kNo, GrProtected::kNo);
        } else {
            backendTex = context->createBackendTexture(kSize, kSize, test.fColorType,
                                                       SkColors::kWhite, GrMipMapped::kNo,
                                                       GrRenderable::kNo, GrProtected::kNo);
        }
        REPORTER_ASSERT(reporter, backendTex.isValid());

        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.fComponents));

            // 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->flush();
        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]);
    }
}
