/*
 * 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 "tests/Test.h"

#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/graphite/CombinationBuilder.h"
#include "include/gpu/graphite/Context.h"
#include "src/core/SkKeyHelpers.h"
#include "src/core/SkRuntimeEffectPriv.h"
#include "src/core/SkShaderCodeDictionary.h"
#include "src/gpu/graphite/ContextPriv.h"

using namespace skgpu::graphite;

#ifdef SK_ENABLE_PRECOMPILE

namespace {

// combines two child blenders using 'blendFrac'
//    1 uniform ("blendFrac")
//    2 children ("a", "b")
// TODO: add a helper function
sk_sp<SkRuntimeEffect> get_combo_effect() {
    SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForBlender(SkString(
            "uniform float blendFrac;"
            "uniform blender a;"
            "uniform blender b;"
            "half4 main(half4 src, half4 dst) {"
                "return (blendFrac * a.eval(src, dst)) + ((1 - blendFrac) * b.eval(src, dst));"
            "}"
        ));

    return result.effect;
}

// returns opaque red w/ the red value determined by 'redColor'
//    1 uniform ("redColor)
sk_sp<SkRuntimeEffect> get_red_effect() {
    SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForBlender(SkString(
            "uniform float redColor;"
            "half4 main(half4 src, half4 dst) {"
                "return half4(redColor, 0, 0, 1);"
            "}"
        ));

    return result.effect;
}

// returns opaque blue w/ the blue value determined by 'blueColor'
//    1 uniform ("blueColor)
sk_sp<SkRuntimeEffect> get_blue_effect() {
    SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForBlender(SkString(
            "uniform float blueColor;"
            "half4 main(half4 src, half4 dst) {"
                "return half4(0, 0, blueColor, 1);"
            "}"
        ));

    return result.effect;
}

static sk_sp<SkBlender> get_blender(sk_sp<SkRuntimeEffect> comboEffect,
                                    sk_sp<SkRuntimeEffect> redEffect,
                                    sk_sp<SkRuntimeEffect> blueEffect) {
    sk_sp<SkBlender> redBlender;
    {
        SkRuntimeBlendBuilder builder(redEffect);
        builder.uniform("redColor") = 1.0f;
        redBlender = builder.makeBlender();
    }

    sk_sp<SkBlender> blueBlender;
    {
        SkRuntimeBlendBuilder builder(blueEffect);
        builder.uniform("blueColor") = 1.0f;
        blueBlender = builder.makeBlender();
    }

    sk_sp<SkBlender> linearBlender;
    {
        SkRuntimeBlendBuilder builder(comboEffect);
        builder.uniform("blendFrac") = 0.5f;
        builder.child("a") = redBlender;
        builder.child("b") = blueBlender;
        linearBlender = builder.makeBlender();
    }

    return linearBlender;
}

} // anonymous namespace

DEF_GRAPHITE_TEST_FOR_CONTEXTS(RTEffectTest, reporter, context) {
    SkShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();

    sk_sp<SkRuntimeEffect> comboEffect = get_combo_effect();
    sk_sp<SkRuntimeEffect> redEffect = get_red_effect();
    sk_sp<SkRuntimeEffect> blueEffect = get_blue_effect();

    BlenderID comboId = context->addUserDefinedBlender(comboEffect);
    SkASSERT(comboId.isValid());

    BlenderID redId = context->addUserDefinedBlender(redEffect);
    SkASSERT(redId.isValid());

    BlenderID blueId = context->addUserDefinedBlender(blueEffect);
    SkASSERT(blueId.isValid());

    auto comboEntry = dict->getEntry(comboId);
    REPORTER_ASSERT(reporter, comboEntry);

    auto redEntry = dict->getEntry(redId);
    REPORTER_ASSERT(reporter, redEntry);

    auto blueEntry = dict->getEntry(blueId);
    REPORTER_ASSERT(reporter, blueEntry);

    // TODO:
    //   add runtime effect shaders and color filters
    //   check that the shader snippet has the expected properties: uniforms, children, functions

    sk_sp<SkBlender> blender = get_blender(comboEffect, redEffect, blueEffect);

    // TODO:
    //   check that the uniforms can be extracted from 'blender' correctly
}

#endif // SK_ENABLE_PRECOMPILE

DEF_GRAPHITE_TEST_FOR_CONTEXTS(Shader_FindOrCreateSnippetForRuntimeEffect, reporter, context) {
    SkShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();

    std::unique_ptr<SkRuntimeEffect> testEffect(SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
        "half4 main(float2 coords) {"
            "return half4(coords.xy01);"
        "}"
    ));

    // Create a new runtime-effect snippet.
    int snippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, snippetID >= kBuiltInCodeSnippetIDCount);

    // Verify that it can be looked up and its name is 'RuntimeEffect'. (The name isn't meaningful,
    // but this is an easy way to verify that we didn't get an unrelated snippet.)
    const SkShaderSnippet* snippet = dict->getEntry(snippetID);
    REPORTER_ASSERT(reporter, snippet);
    REPORTER_ASSERT(reporter, std::string_view(snippet->fName) == "RuntimeEffect");

    // If we pass the same effect again, we should get the same snippet ID as before.
    int foundSnippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, foundSnippetID == snippetID);
}

DEF_GRAPHITE_TEST_FOR_CONTEXTS(ColorFilter_FindOrCreateSnippetForRuntimeEffect, reporter, context) {
    SkShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();

    std::unique_ptr<SkRuntimeEffect> testEffect(SkMakeRuntimeEffect(
            SkRuntimeEffect::MakeForColorFilter,
                "half4 main(half4 color) {"
                    "return color.gbra;"
                "}"
            ));

    // Create a new runtime-effect snippet.
    int snippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, snippetID >= kBuiltInCodeSnippetIDCount);

    // Verify that it can be looked up and its name is 'RuntimeEffect'. (The name isn't meaningful,
    // but this is an easy way to verify that we didn't get an unrelated snippet.)
    const SkShaderSnippet* snippet = dict->getEntry(snippetID);
    REPORTER_ASSERT(reporter, snippet);
    REPORTER_ASSERT(reporter, std::string_view(snippet->fName) == "RuntimeEffect");

    // If we pass the same effect again, we should get the same snippet ID as before.
    int foundSnippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, foundSnippetID == snippetID);
}

DEF_GRAPHITE_TEST_FOR_CONTEXTS(ShaderUniforms_FindOrCreateSnippetForRuntimeEffect,
                               reporter, context) {
    SkShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();

    std::unique_ptr<SkRuntimeEffect> testEffect(SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
        "uniform float3x3 MyFloat3x3Uniform;"
        "uniform int4 MyInt4ArrayUniform[1];"
        "uniform half2 MyHalf2ArrayUniform[99];"
        "half4 main(float2 coords) {"
            "return half4(coords.xy01);"
        "}"
    ));

    // Create a new runtime-effect snippet.
    int snippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, snippetID >= kBuiltInCodeSnippetIDCount);

    // Delete the test effect.
    testEffect = nullptr;

    // Verify that it can be looked up by its snippet ID.
    const SkShaderSnippet* snippet = dict->getEntry(snippetID);
    REPORTER_ASSERT(reporter, snippet);

    // The uniform span should match our expectations even though the runtime effect was deleted.
    REPORTER_ASSERT(reporter, snippet->fUniforms.size() == 4);

    REPORTER_ASSERT(reporter, std::string_view(snippet->fUniforms[0].name()) == "localMatrix");
    REPORTER_ASSERT(reporter, snippet->fUniforms[0].type() == SkSLType::kFloat4x4);
    REPORTER_ASSERT(reporter, snippet->fUniforms[0].count() == 0);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[1].name()) == "MyFloat3x3Uniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[1].type() == SkSLType::kFloat3x3);
    REPORTER_ASSERT(reporter, snippet->fUniforms[1].count() == 0);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[2].name()) == "MyInt4ArrayUniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[2].type() == SkSLType::kInt4);
    REPORTER_ASSERT(reporter, snippet->fUniforms[2].count() == 1);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[3].name()) == "MyHalf2ArrayUniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[3].type() == SkSLType::kHalf2);
    REPORTER_ASSERT(reporter, snippet->fUniforms[3].count() == 99);
}

DEF_GRAPHITE_TEST_FOR_CONTEXTS(ColorFilterUniforms_FindOrCreateSnippetForRuntimeEffect,
                               reporter, context) {
    SkShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();

    std::unique_ptr<SkRuntimeEffect> testEffect(SkMakeRuntimeEffect(
            SkRuntimeEffect::MakeForColorFilter,
                "uniform float3x3 MyFloat3x3Uniform;"
                "uniform int4 MyInt4ArrayUniform[1];"
                "uniform half2 MyHalf2ArrayUniform[99];"
                "half4 main(half4 color) {"
                    "return color.gbra;"
                "}"
            ));

    // Create a new runtime-effect snippet.
    int snippetID = dict->findOrCreateRuntimeEffectSnippet(testEffect.get());
    REPORTER_ASSERT(reporter, snippetID >= kBuiltInCodeSnippetIDCount);

    // Delete the test effect.
    testEffect = nullptr;

    // Verify that it can be looked up by its snippet ID.
    const SkShaderSnippet* snippet = dict->getEntry(snippetID);
    REPORTER_ASSERT(reporter, snippet);

    // The uniform span should match our expectations even though the runtime effect was deleted.
    REPORTER_ASSERT(reporter, snippet->fUniforms.size() == 3);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[0].name()) == "MyFloat3x3Uniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[0].type() == SkSLType::kFloat3x3);
    REPORTER_ASSERT(reporter, snippet->fUniforms[0].count() == 0);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[1].name()) == "MyInt4ArrayUniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[1].type() == SkSLType::kInt4);
    REPORTER_ASSERT(reporter, snippet->fUniforms[1].count() == 1);

    REPORTER_ASSERT(reporter,
                    std::string_view(snippet->fUniforms[2].name()) == "MyHalf2ArrayUniform");
    REPORTER_ASSERT(reporter, snippet->fUniforms[2].type() == SkSLType::kHalf2);
    REPORTER_ASSERT(reporter, snippet->fUniforms[2].count() == 99);
}
