// 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/transform/canonicalize_entry_point_io.h"

#include <utility>

#include "src/program_builder.h"
#include "src/semantic/function.h"
#include "src/semantic/statement.h"
#include "src/semantic/variable.h"

namespace tint {
namespace transform {

CanonicalizeEntryPointIO::CanonicalizeEntryPointIO() = default;
CanonicalizeEntryPointIO::~CanonicalizeEntryPointIO() = default;

Transform::Output CanonicalizeEntryPointIO::Run(const Program* in,
                                                const DataMap&) {
  ProgramBuilder out;
  CloneContext ctx(&out, in);

  // Strip entry point IO decorations from struct declarations.
  // TODO(jrprice): This code is duplicated with the SPIR-V transform.
  for (auto* ty : ctx.src->AST().ConstructedTypes()) {
    if (auto* struct_ty = ty->As<type::Struct>()) {
      // Build new list of struct members without entry point IO decorations.
      ast::StructMemberList new_struct_members;
      for (auto* member : struct_ty->impl()->members()) {
        ast::DecorationList new_decorations = RemoveDecorations(
            &ctx, member->decorations(), [](const ast::Decoration* deco) {
              return deco
                  ->IsAnyOf<ast::BuiltinDecoration, ast::LocationDecoration>();
            });
        new_struct_members.push_back(
            ctx.dst->Member(ctx.Clone(member->symbol()),
                            ctx.Clone(member->type()), new_decorations));
      }

      // Redeclare the struct.
      auto* new_struct = ctx.dst->create<type::Struct>(
          ctx.Clone(struct_ty->symbol()),
          ctx.dst->create<ast::Struct>(
              new_struct_members, ctx.Clone(struct_ty->impl()->decorations())));
      ctx.Replace(struct_ty, new_struct);
    }
  }

  for (auto* func : ctx.src->AST().Functions()) {
    if (!func->IsEntryPoint()) {
      continue;
    }

    ast::VariableList new_parameters;

    if (!func->params().empty()) {
      // Collect all parameters and build a list of new struct members.
      auto new_struct_param_symbol = ctx.dst->Symbols().New();
      ast::StructMemberList new_struct_members;
      for (auto* param : func->params()) {
        auto param_name = ctx.Clone(param->symbol());
        auto* param_ty = ctx.src->Sem().Get(param)->Type();

        ast::Expression* func_const_initializer = nullptr;

        if (auto* struct_ty =
                param_ty->UnwrapAliasIfNeeded()->As<type::Struct>()) {
          // Pull out all struct members and build initializer list.
          ast::ExpressionList init_values;
          for (auto* member : struct_ty->impl()->members()) {
            if (member->type()->UnwrapAll()->Is<type::Struct>()) {
              TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct";
            }

            ast::DecorationList new_decorations = RemoveDecorations(
                &ctx, member->decorations(), [](const ast::Decoration* deco) {
                  return !deco->IsAnyOf<ast::BuiltinDecoration,
                                        ast::LocationDecoration>();
                });
            auto member_name = ctx.Clone(member->symbol());
            new_struct_members.push_back(ctx.dst->Member(
                member_name, ctx.Clone(member->type()), new_decorations));
            init_values.push_back(
                ctx.dst->MemberAccessor(new_struct_param_symbol, member_name));
          }

          func_const_initializer =
              ctx.dst->Construct(ctx.Clone(param_ty), init_values);
        } else {
          ast::DecorationList new_decorations = RemoveDecorations(
              &ctx, param->decorations(), [](const ast::Decoration* deco) {
                return !deco->IsAnyOf<ast::BuiltinDecoration,
                                      ast::LocationDecoration>();
              });
          new_struct_members.push_back(ctx.dst->Member(
              param_name, ctx.Clone(param_ty), new_decorations));
          func_const_initializer =
              ctx.dst->MemberAccessor(new_struct_param_symbol, param_name);
        }

        if (func->body()->empty()) {
          // Don't generate a function-scope const if the function is empty.
          continue;
        }

        // Create a function-scope const to replace the parameter.
        // Initialize it with the value extracted from the new struct parameter.
        auto* func_const = ctx.dst->Const(param_name, ctx.Clone(param_ty),
                                          func_const_initializer);
        ctx.InsertBefore(func->body()->statements(), *func->body()->begin(),
                         ctx.dst->WrapInStatement(func_const));

        // Replace all uses of the function parameter with the function const.
        for (auto* user : ctx.src->Sem().Get(param)->Users()) {
          ctx.Replace<ast::Expression>(user->Declaration(),
                                       ctx.dst->Expr(param_name));
        }
      }

      // Create the new struct type.
      auto* in_struct = ctx.dst->create<type::Struct>(
          ctx.dst->Symbols().New(),
          ctx.dst->create<ast::Struct>(new_struct_members,
                                       ast::DecorationList{}));
      ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, in_struct);

      // Create a new function parameter using this struct type.
      auto* struct_param = ctx.dst->Var(new_struct_param_symbol, in_struct,
                                        ast::StorageClass::kNone);
      new_parameters.push_back(struct_param);
    }

    // Handle return type.
    auto* ret_type = func->return_type()->UnwrapAliasIfNeeded();
    type::Type* new_ret_type;
    if (ret_type->Is<type::Void>()) {
      new_ret_type = ctx.dst->ty.void_();
    } else {
      ast::StructMemberList new_struct_members;

      if (auto* struct_ty = ret_type->As<type::Struct>()) {
        // Rebuild struct with only the entry point IO attributes.
        for (auto* member : struct_ty->impl()->members()) {
          if (member->type()->UnwrapAll()->Is<type::Struct>()) {
            TINT_ICE(ctx.dst->Diagnostics()) << "nested pipeline IO struct";
          }

          ast::DecorationList new_decorations = RemoveDecorations(
              &ctx, member->decorations(), [](const ast::Decoration* deco) {
                return !deco->IsAnyOf<ast::BuiltinDecoration,
                                      ast::LocationDecoration>();
              });
          new_struct_members.push_back(
              ctx.dst->Member(ctx.Clone(member->symbol()),
                              ctx.Clone(member->type()), new_decorations));
        }
      } else {
        new_struct_members.push_back(
            ctx.dst->Member("value", ctx.Clone(ret_type),
                            ctx.Clone(func->return_type_decorations())));
      }

      // Create the new struct type.
      auto* out_struct = ctx.dst->create<type::Struct>(
          ctx.dst->Symbols().New(),
          ctx.dst->create<ast::Struct>(new_struct_members,
                                       ast::DecorationList{}));
      ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func, out_struct);
      new_ret_type = out_struct;

      // Replace all return statements.
      auto* sem_func = ctx.src->Sem().Get(func);
      for (auto* ret : sem_func->ReturnStatements()) {
        auto* ret_sem = ctx.src->Sem().Get(ret);
        // Reconstruct the return value using the newly created struct.
        auto* new_ret_value = ctx.Clone(ret->value());
        ast::ExpressionList ret_values;
        if (auto* struct_ty = ret_type->As<type::Struct>()) {
          if (!ret->value()->Is<ast::IdentifierExpression>()) {
            // Create a const to hold the return value expression to avoid
            // re-evaluating it multiple times.
            auto temp = ctx.dst->Symbols().New();
            auto* temp_var = ctx.dst->Decl(
                ctx.dst->Const(temp, ctx.Clone(ret_type), new_ret_value));
            ctx.InsertBefore(ret_sem->Block()->statements(), ret, temp_var);
            new_ret_value = ctx.dst->Expr(temp);
          }

          for (auto* member : struct_ty->impl()->members()) {
            ret_values.push_back(ctx.dst->MemberAccessor(
                new_ret_value, ctx.Clone(member->symbol())));
          }
        } else {
          ret_values.push_back(new_ret_value);
        }

        auto* new_ret = ctx.dst->create<ast::ReturnStatement>(
            ctx.dst->Construct(new_ret_type, ret_values));
        ctx.Replace(ret, new_ret);
      }
    }

    // Rewrite the function header with the new parameters.
    auto* new_func = ctx.dst->create<ast::Function>(
        func->source(), ctx.Clone(func->symbol()), new_parameters, new_ret_type,
        ctx.Clone(func->body()), ctx.Clone(func->decorations()),
        ast::DecorationList{});
    ctx.Replace(func, new_func);
  }

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

}  // namespace transform
}  // namespace tint
