// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/tint/transform/multiplanar_external_texture.h"

#include <string>
#include <vector>

#include "src/tint/ast/function.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/call.h"
#include "src/tint/sem/function.h"
#include "src/tint/sem/variable.h"
#include "src/tint/type/texture_dimension.h"

TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture);
TINT_INSTANTIATE_TYPEINFO(tint::transform::MultiplanarExternalTexture::NewBindingPoints);

using namespace tint::number_suffixes;  // NOLINT

namespace tint::transform {
namespace {

bool ShouldRun(const Program* program) {
    for (auto* node : program->ASTNodes().Objects()) {
        if (auto* ty = node->As<ast::Type>()) {
            if (program->Sem().Get<type::ExternalTexture>(ty)) {
                return true;
            }
        }
    }
    return false;
}

/// This struct stores symbols for new bindings created as a result of transforming a
/// texture_external instance.
struct NewBindingSymbols {
    Symbol params;
    Symbol plane_0;
    Symbol plane_1;
};
}  // namespace

/// PIMPL state for the transform
struct MultiplanarExternalTexture::State {
    /// The clone context.
    CloneContext& ctx;

    /// ProgramBuilder for the context
    ProgramBuilder& b;

    /// Destination binding locations for the expanded texture_external provided
    /// as input into the transform.
    const NewBindingPoints* new_binding_points;

    /// Symbol for the GammaTransferParams
    Symbol gamma_transfer_struct_sym;

    /// Symbol for the ExternalTextureParams struct
    Symbol params_struct_sym;

    /// Symbol for the textureLoadExternal functions
    utils::Hashmap<const sem::CallTarget*, Symbol, 2> texture_load_external_fns;

    /// Symbol for the textureSampleExternal function
    Symbol texture_sample_external_sym;

    /// Symbol for the textureSampleExternalDEPRECATED function
    Symbol texture_sample_external_deprecated_sym;

    /// Symbol for the gammaCorrection function
    Symbol gamma_correction_sym;

    /// Storage for new bindings that have been created corresponding to an original
    /// texture_external binding.
    std::unordered_map<const sem::Variable*, NewBindingSymbols> new_binding_symbols;

    /// Constructor
    /// @param context the clone
    /// @param newBindingPoints the input destination binding locations for the
    /// expanded texture_external
    State(CloneContext& context, const NewBindingPoints* newBindingPoints)
        : ctx(context), b(*context.dst), new_binding_points(newBindingPoints) {}

    /// Processes the module
    void Process() {
        auto& sem = ctx.src->Sem();

        // For each texture_external binding, we replace it with a texture_2d<f32> binding and
        // create two additional bindings (one texture_2d<f32> to represent the secondary plane and
        // one uniform buffer for the ExternalTextureParams struct).
        for (auto* global : ctx.src->AST().GlobalVariables()) {
            auto* sem_var = sem.Get<sem::GlobalVariable>(global);
            if (!sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
                continue;
            }

            // If the attributes are empty, then this must be a texture_external passed as a
            // function parameter. These variables are transformed elsewhere.
            if (global->attributes.IsEmpty()) {
                continue;
            }

            // If we find a texture_external binding, we know we must emit the ExternalTextureParams
            // struct.
            if (!params_struct_sym.IsValid()) {
                createExtTexParamsStructs();
            }

            // The binding points for the newly introduced bindings must have been provided to this
            // transform. We fetch the new binding points by providing the original texture_external
            // binding points into the passed map.
            BindingPoint bp = sem_var->BindingPoint();

            BindingsMap::const_iterator it = new_binding_points->bindings_map.find(bp);
            if (it == new_binding_points->bindings_map.end()) {
                b.Diagnostics().add_error(
                    diag::System::Transform,
                    "missing new binding points for texture_external at binding {" +
                        std::to_string(bp.group) + "," + std::to_string(bp.binding) + "}");
                continue;
            }

            BindingPoints bps = it->second;

            // Symbols for the newly created bindings must be saved so they can be passed as
            // parameters later. These are placed in a map and keyed by the source symbol associated
            // with the texture_external binding that corresponds with the new destination bindings.
            // NewBindingSymbols new_binding_syms;
            auto& syms = new_binding_symbols[sem_var];
            syms.plane_0 = ctx.Clone(global->symbol);
            syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
            b.GlobalVar(syms.plane_1, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                        b.Group(AInt(bps.plane_1.group)), b.Binding(AInt(bps.plane_1.binding)));
            syms.params = b.Symbols().New("ext_tex_params");
            b.GlobalVar(syms.params, b.ty("ExternalTextureParams"), type::AddressSpace::kUniform,
                        b.Group(AInt(bps.params.group)), b.Binding(AInt(bps.params.binding)));

            // Replace the original texture_external binding with a texture_2d<f32> binding.
            auto cloned_attributes = ctx.Clone(global->attributes);
            const ast::Expression* cloned_initializer = ctx.Clone(global->initializer);

            auto* replacement =
                b.Var(syms.plane_0, b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32()),
                      cloned_initializer, cloned_attributes);
            ctx.Replace(global, replacement);
        }

        // We must update all the texture_external parameters for user declared functions.
        for (auto* fn : ctx.src->AST().Functions()) {
            for (const ast::Variable* param : fn->params) {
                if (auto* sem_var = sem.Get(param)) {
                    if (!sem_var->Type()->UnwrapRef()->Is<type::ExternalTexture>()) {
                        continue;
                    }
                    // If we find a texture_external, we must ensure the ExternalTextureParams
                    // struct exists.
                    if (!params_struct_sym.IsValid()) {
                        createExtTexParamsStructs();
                    }
                    // When a texture_external is found, we insert all components the
                    // texture_external into the parameter list. We must also place the new symbols
                    // into the transform state so they can be used when transforming function
                    // calls.
                    auto& syms = new_binding_symbols[sem_var];
                    syms.plane_0 = ctx.Clone(param->symbol);
                    syms.plane_1 = b.Symbols().New("ext_tex_plane_1");
                    syms.params = b.Symbols().New("ext_tex_params");
                    auto tex2d_f32 = [&] {
                        return b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32());
                    };
                    ctx.Replace(param, b.Param(syms.plane_0, tex2d_f32()));
                    ctx.InsertAfter(fn->params, param, b.Param(syms.plane_1, tex2d_f32()));
                    ctx.InsertAfter(fn->params, param,
                                    b.Param(syms.params, b.ty(params_struct_sym)));
                }
            }
        }

        // Transform the external texture builtin calls into calls to the external texture
        // functions.
        ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* {
            auto* call = sem.Get(expr)->UnwrapMaterialize()->As<sem::Call>();
            auto* builtin = call->Target()->As<sem::Builtin>();

            if (builtin && !builtin->Parameters().IsEmpty() &&
                builtin->Parameters()[0]->Type()->Is<type::ExternalTexture>() &&
                builtin->Type() != sem::BuiltinType::kTextureDimensions) {
                if (auto* var_user =
                        sem.GetVal(expr->args[0])->UnwrapLoad()->As<sem::VariableUser>()) {
                    auto it = new_binding_symbols.find(var_user->Variable());
                    if (it == new_binding_symbols.end()) {
                        // If valid new binding locations were not provided earlier, we would have
                        // been unable to create these symbols. An error message was emitted
                        // earlier, so just return early to avoid internal compiler errors and
                        // retain a clean error message.
                        return nullptr;
                    }
                    auto& syms = it->second;

                    switch (builtin->Type()) {
                        case sem::BuiltinType::kTextureLoad:
                            return createTextureLoad(call, syms);
                        case sem::BuiltinType::kTextureSampleBaseClampToEdge:
                            return createTextureSampleBaseClampToEdge(expr, syms);
                        default:
                            break;
                    }
                }
            } else if (call->Target()->Is<sem::Function>()) {
                // The call expression may be to a user-defined function that contains a
                // texture_external parameter. These need to be expanded out to multiple plane
                // textures and the texture parameters structure.
                for (auto* arg : expr->args) {
                    if (auto* var_user = sem.GetVal(arg)->UnwrapLoad()->As<sem::VariableUser>()) {
                        // Check if a parameter is a texture_external by trying to find
                        // it in the transform state.
                        auto it = new_binding_symbols.find(var_user->Variable());
                        if (it != new_binding_symbols.end()) {
                            auto& syms = it->second;
                            // When we find a texture_external, we must unpack it into its
                            // components.
                            ctx.Replace(arg, b.Expr(syms.plane_0));
                            ctx.InsertAfter(expr->args, arg, b.Expr(syms.plane_1));
                            ctx.InsertAfter(expr->args, arg, b.Expr(syms.params));
                        }
                    }
                }
            }

            return nullptr;
        });
    }

    /// Creates the parameter structs associated with the transform.
    void createExtTexParamsStructs() {
        // Create GammaTransferParams struct.
        utils::Vector gamma_transfer_member_list{
            b.Member("G", b.ty.f32()), b.Member("A", b.ty.f32()),      b.Member("B", b.ty.f32()),
            b.Member("C", b.ty.f32()), b.Member("D", b.ty.f32()),      b.Member("E", b.ty.f32()),
            b.Member("F", b.ty.f32()), b.Member("padding", b.ty.u32())};

        gamma_transfer_struct_sym = b.Symbols().New("GammaTransferParams");

        b.Structure(gamma_transfer_struct_sym, gamma_transfer_member_list);

        // Create ExternalTextureParams struct.
        utils::Vector ext_tex_params_member_list{
            b.Member("numPlanes", b.ty.u32()),
            b.Member("doYuvToRgbConversionOnly", b.ty.u32()),
            b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4<f32>()),
            b.Member("gammaDecodeParams", b.ty("GammaTransferParams")),
            b.Member("gammaEncodeParams", b.ty("GammaTransferParams")),
            b.Member("gamutConversionMatrix", b.ty.mat3x3<f32>()),
            b.Member("coordTransformationMatrix", b.ty.mat3x2<f32>())};

        params_struct_sym = b.Symbols().New("ExternalTextureParams");

        b.Structure(params_struct_sym, ext_tex_params_member_list);
    }

    /// Creates the gammaCorrection function if needed and returns a call
    /// expression to it.
    void createGammaCorrectionFn() {
        gamma_correction_sym = b.Symbols().New("gammaCorrection");

        b.Func(
            gamma_correction_sym,
            utils::Vector{
                b.Param("v", b.ty.vec3<f32>()),
                b.Param("params", b.ty(gamma_transfer_struct_sym)),
            },
            b.ty.vec3<f32>(),
            utils::Vector{
                // let cond = abs(v) < vec3(params.D);
                b.Decl(b.Let("cond", b.LessThan(b.Call("abs", "v"),
                                                b.vec3<f32>(b.MemberAccessor("params", "D"))))),
                // let t = sign(v) * ((params.C * abs(v)) + params.F);
                b.Decl(b.Let("t",
                             b.Mul(b.Call("sign", "v"),
                                   b.Add(b.Mul(b.MemberAccessor("params", "C"), b.Call("abs", "v")),
                                         b.MemberAccessor("params", "F"))))),
                // let f = (sign(v) * pow(((params.A * abs(v)) + params.B),
                // vec3(params.G))) + params.E;
                b.Decl(b.Let("f", b.Mul(b.Call("sign", "v"),
                                        b.Add(b.Call("pow",
                                                     b.Add(b.Mul(b.MemberAccessor("params", "A"),
                                                                 b.Call("abs", "v")),
                                                           b.MemberAccessor("params", "B")),
                                                     b.vec3<f32>(b.MemberAccessor("params", "G"))),
                                              b.MemberAccessor("params", "E"))))),
                // return select(f, t, cond);
                b.Return(b.Call("select", "f", "t", "cond")),
            });
    }

    /// Constructs a StatementList containing all the statements making up the body of the texture
    /// builtin function.
    /// @param call_type determines which function body to generate
    /// @returns a statement list that makes of the body of the chosen function
    auto buildTextureBuiltinBody(sem::BuiltinType call_type) {
        utils::Vector<const ast::Statement*, 16> stmts;
        const ast::CallExpression* single_plane_call = nullptr;
        const ast::CallExpression* plane_0_call = nullptr;
        const ast::CallExpression* plane_1_call = nullptr;
        switch (call_type) {
            case sem::BuiltinType::kTextureSampleBaseClampToEdge:
                stmts.Push(b.Decl(b.Let(
                    "modifiedCoords", b.Mul(b.MemberAccessor("params", "coordTransformationMatrix"),
                                            b.vec3<f32>("coord", 1_a)))));

                stmts.Push(b.Decl(
                    b.Let("plane0_dims",
                          b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane0", 0_a)))));
                stmts.Push(
                    b.Decl(b.Let("plane0_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane0_dims"))));
                stmts.Push(b.Decl(
                    b.Let("plane0_clamped", b.Call("clamp", "modifiedCoords", "plane0_half_texel",
                                                   b.Sub(1_a, "plane0_half_texel")))));
                stmts.Push(b.Decl(
                    b.Let("plane1_dims",
                          b.Call(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane1", 0_a)))));
                stmts.Push(
                    b.Decl(b.Let("plane1_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane1_dims"))));
                stmts.Push(b.Decl(
                    b.Let("plane1_clamped", b.Call("clamp", "modifiedCoords", "plane1_half_texel",
                                                   b.Sub(1_a, "plane1_half_texel")))));

                // textureSampleLevel(plane0, smp, plane0_clamped, 0.0);
                single_plane_call =
                    b.Call("textureSampleLevel", "plane0", "smp", "plane0_clamped", 0_a);
                // textureSampleLevel(plane0, smp, plane0_clamped, 0.0);
                plane_0_call = b.Call("textureSampleLevel", "plane0", "smp", "plane0_clamped", 0_a);
                // textureSampleLevel(plane1, smp, plane1_clamped, 0.0);
                plane_1_call = b.Call("textureSampleLevel", "plane1", "smp", "plane1_clamped", 0_a);
                break;
            case sem::BuiltinType::kTextureLoad:
                // textureLoad(plane0, coord, 0);
                single_plane_call = b.Call("textureLoad", "plane0", "coord", 0_a);
                // textureLoad(plane0, coord, 0);
                plane_0_call = b.Call("textureLoad", "plane0", "coord", 0_a);
                // textureLoad(plane1, coord, 0);
                plane_1_call = b.Call("textureLoad", "plane1", "coord", 0_a);
                break;
            default:
                TINT_ICE(Transform, b.Diagnostics()) << "unhandled builtin: " << call_type;
        }

        // var color: vec3<f32>;
        stmts.Push(b.Decl(b.Var("color", b.ty.vec3(b.ty.f32()))));

        // if ((params.numPlanes == 1u))
        stmts.Push(
            b.If(b.Equal(b.MemberAccessor("params", "numPlanes"), b.Expr(1_a)),
                 b.Block(
                     // color = textureLoad(plane0, coord, 0).rgb;
                     b.Assign("color", b.MemberAccessor(single_plane_call, "rgb"))),
                 b.Else(b.Block(
                     // color = vec4<f32>(plane_0_call.r, plane_1_call.rg, 1.0) *
                     //         params.yuvToRgbConversionMatrix;
                     b.Assign("color",
                              b.Mul(b.vec4<f32>(b.MemberAccessor(plane_0_call, "r"),
                                                b.MemberAccessor(plane_1_call, "rg"), 1_a),
                                    b.MemberAccessor("params", "yuvToRgbConversionMatrix")))))));

        // if (params.doYuvToRgbConversionOnly == 0u)
        stmts.Push(
            b.If(b.Equal(b.MemberAccessor("params", "doYuvToRgbConversionOnly"), b.Expr(0_a)),
                 b.Block(
                     // color = gammaConversion(color, gammaDecodeParams);
                     b.Assign("color", b.Call("gammaCorrection", "color",
                                              b.MemberAccessor("params", "gammaDecodeParams"))),
                     // color = (params.gamutConversionMatrix * color);
                     b.Assign("color",
                              b.Mul(b.MemberAccessor("params", "gamutConversionMatrix"), "color")),
                     // color = gammaConversion(color, gammaEncodeParams);
                     b.Assign("color", b.Call("gammaCorrection", "color",
                                              b.MemberAccessor("params", "gammaEncodeParams"))))));

        // return vec4<f32>(color, 1.f);
        stmts.Push(b.Return(b.vec4<f32>("color", 1_a)));

        return stmts;
    }

    /// Creates the textureSampleExternal function if needed and returns a call expression to it.
    /// @param expr the call expression being transformed
    /// @param syms the expanded symbols to be used in the new call
    /// @returns a call expression to textureSampleExternal
    const ast::CallExpression* createTextureSampleBaseClampToEdge(const ast::CallExpression* expr,
                                                                  NewBindingSymbols syms) {
        const ast::Expression* plane_0_binding_param = ctx.Clone(expr->args[0]);

        if (TINT_UNLIKELY(expr->args.Length() != 3)) {
            TINT_ICE(Transform, b.Diagnostics())
                << "expected textureSampleBaseClampToEdge call with a "
                   "texture_external to have 3 parameters, found "
                << expr->args.Length() << " parameters";
        }

        // TextureSampleExternal calls the gammaCorrection function, so ensure it
        // exists.
        if (!gamma_correction_sym.IsValid()) {
            createGammaCorrectionFn();
        }

        if (!texture_sample_external_sym.IsValid()) {
            texture_sample_external_sym = b.Symbols().New("textureSampleExternal");

            // Emit the textureSampleExternal function.
            b.Func(texture_sample_external_sym,
                   utils::Vector{
                       b.Param("plane0",
                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
                       b.Param("plane1",
                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
                       b.Param("smp", b.ty.sampler(type::SamplerKind::kSampler)),
                       b.Param("coord", b.ty.vec2(b.ty.f32())),
                       b.Param("params", b.ty(params_struct_sym)),
                   },
                   b.ty.vec4(b.ty.f32()),
                   buildTextureBuiltinBody(sem::BuiltinType::kTextureSampleBaseClampToEdge));
        }

        return b.Call(texture_sample_external_sym, utils::Vector{
                                                       plane_0_binding_param,
                                                       b.Expr(syms.plane_1),
                                                       ctx.Clone(expr->args[1]),
                                                       ctx.Clone(expr->args[2]),
                                                       b.Expr(syms.params),
                                                   });
    }

    /// Creates the textureLoadExternal function if needed and returns a call expression to it.
    /// @param call the call expression being transformed
    /// @param syms the expanded symbols to be used in the new call
    /// @returns a call expression to textureLoadExternal
    const ast::CallExpression* createTextureLoad(const sem::Call* call, NewBindingSymbols syms) {
        if (TINT_UNLIKELY(call->Arguments().Length() != 2)) {
            TINT_ICE(Transform, b.Diagnostics())
                << "expected textureLoad call with a texture_external to have 2 arguments, found "
                << call->Arguments().Length() << " arguments";
        }

        auto& args = call->Arguments();

        // TextureLoadExternal calls the gammaCorrection function, so ensure it exists.
        if (!gamma_correction_sym.IsValid()) {
            createGammaCorrectionFn();
        }

        auto texture_load_external_sym = texture_load_external_fns.GetOrCreate(call->Target(), [&] {
            auto& sig = call->Target()->Signature();
            auto* coord_ty = sig.Parameter(sem::ParameterUsage::kCoords)->Type();

            auto name = b.Symbols().New("textureLoadExternal");

            // Emit the textureLoadExternal() function.
            b.Func(name,
                   utils::Vector{
                       b.Param("plane0",
                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
                       b.Param("plane1",
                               b.ty.sampled_texture(type::TextureDimension::k2d, b.ty.f32())),
                       b.Param("coord", CreateASTTypeFor(ctx, coord_ty)),
                       b.Param("params", b.ty(params_struct_sym)),
                   },
                   b.ty.vec4(b.ty.f32()),  //
                   buildTextureBuiltinBody(sem::BuiltinType::kTextureLoad));

            return name;
        });

        auto plane_0_binding_arg = ctx.Clone(args[0]->Declaration());

        return b.Call(texture_load_external_sym, plane_0_binding_arg, syms.plane_1,
                      ctx.Clone(args[1]->Declaration()), syms.params);
    }
};

MultiplanarExternalTexture::NewBindingPoints::NewBindingPoints(BindingsMap inputBindingsMap)
    : bindings_map(std::move(inputBindingsMap)) {}
MultiplanarExternalTexture::NewBindingPoints::~NewBindingPoints() = default;

MultiplanarExternalTexture::MultiplanarExternalTexture() = default;
MultiplanarExternalTexture::~MultiplanarExternalTexture() = default;

// Within this transform, an instance of a texture_external binding is unpacked into two
// texture_2d<f32> bindings representing two possible planes of a single texture and a uniform
// buffer binding representing a struct of parameters. Calls to texture builtins that contain a
// texture_external parameter will be transformed into a newly generated version of the function,
// which can perform the desired operation on a single RGBA plane or on separate Y and UV planes.
Transform::ApplyResult MultiplanarExternalTexture::Apply(const Program* src,
                                                         const DataMap& inputs,
                                                         DataMap&) const {
    auto* new_binding_points = inputs.Get<NewBindingPoints>();

    if (!ShouldRun(src)) {
        return SkipTransform;
    }

    ProgramBuilder b;
    CloneContext ctx{&b, src, /* auto_clone_symbols */ true};
    if (!new_binding_points) {
        b.Diagnostics().add_error(diag::System::Transform, "missing new binding point data for " +
                                                               std::string(TypeInfo().name));
        return Program(std::move(b));
    }

    State state(ctx, new_binding_points);

    state.Process();

    ctx.Clone();
    return Program(std::move(b));
}

}  // namespace tint::transform
