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

#include <memory>
#include <unordered_set>
#include <utility>

#include "src/program_builder.h"
#include "src/semantic/call.h"
#include "src/semantic/member_accessor_expression.h"

TINT_INSTANTIATE_TYPEINFO(tint::transform::Renamer::Data);

namespace tint {
namespace transform {

Renamer::Data::Data(Remappings&& r) : remappings(std::move(r)) {}

Renamer::Data::Data(const Data&) = default;

Renamer::Data::~Data() = default;

Renamer::Renamer() : cfg_{} {}

Renamer::Renamer(const Config& config) : cfg_(config) {}

Renamer::~Renamer() = default;

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

  // Swizzles and intrinsic calls need to keep their symbols preserved.
  std::unordered_set<ast::IdentifierExpression*> preserve;
  for (auto* node : in->ASTNodes().Objects()) {
    if (auto* member = node->As<ast::MemberAccessorExpression>()) {
      auto* sem = in->Sem().Get(member);
      if (!sem) {
        TINT_ICE(out.Diagnostics())
            << "MemberAccessorExpression has no semantic info";
        continue;
      }
      if (sem->IsSwizzle()) {
        preserve.emplace(member->member());
      }
    } else if (auto* call = node->As<ast::CallExpression>()) {
      auto* sem = in->Sem().Get(call);
      if (!sem) {
        TINT_ICE(out.Diagnostics()) << "CallExpression has no semantic info";
        continue;
      }
      if (sem->Target()->Is<semantic::Intrinsic>()) {
        preserve.emplace(call->func()->As<ast::IdentifierExpression>());
      }
    }
  }

  Data::Remappings remappings;

  switch (cfg_.method) {
    case Method::kMonotonic:
      ctx.ReplaceAll([&](Symbol sym) {
        auto str_in = in->Symbols().NameFor(sym);
        auto it = remappings.find(str_in);
        if (it != remappings.end()) {
          return out.Symbols().Get(it->second);
        }
        auto str_out = "_tint_" + std::to_string(remappings.size() + 1);
        remappings.emplace(str_in, str_out);
        return out.Symbols().Register(str_out);
      });

      ctx.ReplaceAll(
          [&](ast::IdentifierExpression* ident) -> ast::IdentifierExpression* {
            if (preserve.count(ident)) {
              auto sym_in = ident->symbol();
              auto str = in->Symbols().NameFor(sym_in);
              auto sym_out = out.Symbols().Register(str);
              return ctx.dst->create<ast::IdentifierExpression>(
                  ctx.Clone(ident->source()), sym_out);
            }
            return nullptr;  // Clone ident. Uses the symbol remapping above.
          });
      break;
  }
  ctx.Clone();

  return Output(Program(std::move(out)),
                std::make_unique<Data>(std::move(remappings)));
}

}  // namespace transform
}  // namespace tint
