/*
 * 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/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/GrContext.h"
#include "src/core/SkTLazy.h"
#include "tests/Test.h"

#include <algorithm>

DEF_TEST(SkRuntimeEffectInvalid, r) {
    auto test = [r](const char* hdr, const char* body, const char* expected) {
        SkString src = SkStringPrintf("%s void main(float2 p, inout half4 color) { %s }",
                                      hdr, body);
        auto[effect, errorText] = SkRuntimeEffect::Make(src);
        REPORTER_ASSERT(r, !effect);
        REPORTER_ASSERT(r, errorText.contains(expected),
                        "Expected error message to contain \"%s\". Actual message: \"%s\"",
                        expected, errorText.c_str());
    };

    // Features that are only allowed in .fp files (key, in uniform, ctype, when, tracked).
    // Ensure that these fail, and the error messages contain the relevant keyword.
    test("layout(key) in bool Input;", "", "key");
    test("in uniform float Input;", "", "in uniform");
    test("layout(ctype=SkRect) float4 Input;", "", "ctype");
    test("in bool Flag; layout(when=Flag) uniform float Input;", "", "when");
    test("layout(tracked) uniform float Input;", "", "tracked");

    // Runtime SkSL supports a limited set of uniform types. No samplers, for example:
    test("uniform sampler2D s;", "", "sampler2D");

    // 'in' variables can't be arrays
    test("in int Input[2];", "", "array");

    // Type specific restrictions:

    // 'bool', 'int' can't be 'uniform'
    test("uniform bool Input;", "", "'uniform'");
    test("uniform int Input;", "", "'uniform'");

    // vector and matrix types can't be 'in'
    test("in float2 Input;", "", "'in'");
    test("in half3x3 Input;", "", "'in'");

    test("half missing();", "color.r = missing();", "undefined function");
}

// Our packing rules and unit test code here relies on this:
static_assert(sizeof(bool) == 1);

class TestEffect {
public:
    TestEffect(skiatest::Reporter* r, const char* hdr, const char* body) {
        SkString src = SkStringPrintf("%s void main(float2 p, inout half4 color) { %s }",
                                      hdr, body);
        auto[effect, errorText] = SkRuntimeEffect::Make(src);
        if (!effect) {
            REPORT_FAILURE(r, "effect",
                           SkStringPrintf("Effect didn't compile: %s", errorText.c_str()));
            return;
        }

        fBuilder.init(std::move(effect));
    }

    SkRuntimeShaderBuilder::BuilderInput operator[](const char* name) {
        return fBuilder->input(name);
    }

    void test(skiatest::Reporter* r, sk_sp<SkSurface> surface,
              uint32_t TL, uint32_t TR, uint32_t BL, uint32_t BR, SkScalar rotate = 0.0f) {
        auto shader = fBuilder->makeShader(nullptr, false);
        if (!shader) {
            REPORT_FAILURE(r, "shader", SkString("Effect didn't produce a shader"));
            return;
        }

        SkPaint paint;
        paint.setShader(std::move(shader));
        paint.setBlendMode(SkBlendMode::kSrc);
        surface->getCanvas()->rotate(rotate);
        surface->getCanvas()->drawPaint(paint);

        uint32_t actual[4];
        SkImageInfo info = surface->imageInfo();
        if (!surface->readPixels(info, actual, info.minRowBytes(), 0, 0)) {
            REPORT_FAILURE(r, "readPixels", SkString("readPixels failed"));
            return;
        }

        uint32_t expected[4] = {TL, TR, BL, BR};
        if (memcmp(actual, expected, sizeof(actual)) != 0) {
            REPORT_FAILURE(r, "Runtime effect didn't match expectations",
                           SkStringPrintf("\n"
                                          "Expected: [ %08x %08x %08x %08x ]\n"
                                          "Got     : [ %08x %08x %08x %08x ]\n"
                                          "SkSL:\n%s\n",
                                          TL, TR, BL, BR, actual[0], actual[1], actual[2],
                                          actual[3], fBuilder->fEffect->source().c_str()));
        }
    }

    void test(skiatest::Reporter* r, sk_sp<SkSurface> surface, uint32_t expected) {
        this->test(r, surface, expected, expected, expected, expected);
    }

private:
    SkTLazy<SkRuntimeShaderBuilder> fBuilder;
};

static void test_RuntimeEffect_Shaders(skiatest::Reporter* r, GrContext* context) {
    SkImageInfo info = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface;
    if (context) {
        surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info);
    } else {
        surface = SkSurface::MakeRaster(info);
    }
    REPORTER_ASSERT(r, surface);

    TestEffect xy(r, "", "color = half4(half2(p - 0.5), 0, 1);");
    xy.test(r, surface, 0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF);

    using float4 = std::array<float, 4>;

    // NOTE: For now, we always emit valid premul colors, until CPU and GPU agree on clamping
    TestEffect uniformColor(r, "uniform float4 gColor;", "color = half4(gColor);");

    uniformColor["gColor"] = float4{ 0.0f, 0.25f, 0.75f, 1.0f };
    uniformColor.test(r, surface, 0xFFBF4000);

    uniformColor["gColor"] = float4{ 0.75f, 0.25f, 0.0f, 1.0f };
    uniformColor.test(r, surface, 0xFF0040BF);

    TestEffect pickColor(r, "in int flag; uniform half4 gColors[2];", "color = gColors[flag];");
    pickColor["gColors"] =
            std::array<float4, 2>{float4{1.0f, 0.0f, 0.0f, 0.498f}, float4{0.0f, 1.0f, 0.0f, 1.0f}};
    pickColor["flag"] = 0;
    pickColor.test(r, surface, 0x7F00007F);  // Tests that we clamp to valid premul
    pickColor["flag"] = 1;
    pickColor.test(r, surface, 0xFF00FF00);

    TestEffect inlineColor(r, "in half c;", "color = half4(c, c, c, 1);");
    inlineColor["c"] = 0.498f;
    inlineColor.test(r, surface, 0xFF7F7F7F);

    // Test sk_FragCoord, which we output to color. Since the surface is 2x2, we should see
    // (0,0), (1,0), (0,1), (1,1), multiply by 0.498 to make sure we're not saturating unexpectedly.
    TestEffect fragCoord(r, "", "color = half4(0.498 * (half2(sk_FragCoord.xy) - 0.5), 0, 1);");
    fragCoord.test(r, surface, 0xFF000000, 0xFF00007F, 0xFF007F00, 0xFF007F7F, 45.0f);
}

DEF_TEST(SkRuntimeEffectSimple, r) {
    test_RuntimeEffect_Shaders(r, nullptr);
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRuntimeEffectSimple_GPU, r, ctxInfo) {
    test_RuntimeEffect_Shaders(r, ctxInfo.grContext());
}
