// 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 <string>

#include "gtest/gtest.h"

#include "src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/mutator.h"
#include "src/tint/fuzzers/tint_ast_fuzzer/probability_context.h"

#include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"

#include "src/tint/ast/call_statement.h"
#include "src/tint/program_builder.h"
#include "src/tint/reader/wgsl/parser.h"
#include "src/tint/writer/wgsl/generator.h"

namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {

TEST(ReplaceIdentifierTest, NotApplicable_Simple) {
  std::string content = R"(
    fn main() {
      let a = 5;
      let c = 6;
      let b = a + 5;

      let d = vec2<i32>(1, 2);
      let e = d.x;
    }
  )";
  Source::File file("test.wgsl", content);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  const auto& main_fn_stmts = program.AST().Functions()[0]->body->statements;

  const auto* a_var =
      main_fn_stmts[0]->As<ast::VariableDeclStatement>()->variable;
  ASSERT_NE(a_var, nullptr);

  const auto* b_var =
      main_fn_stmts[2]->As<ast::VariableDeclStatement>()->variable;
  ASSERT_NE(b_var, nullptr);

  const auto* e_var =
      main_fn_stmts[4]->As<ast::VariableDeclStatement>()->variable;
  ASSERT_NE(e_var, nullptr);

  auto a_var_id = node_id_map.GetId(a_var);
  ASSERT_NE(a_var_id, 0);

  auto b_var_id = node_id_map.GetId(b_var);
  ASSERT_NE(b_var_id, 0);

  const auto* sum_expr = b_var->constructor->As<ast::BinaryExpression>();
  ASSERT_NE(sum_expr, nullptr);

  auto a_ident_id = node_id_map.GetId(sum_expr->lhs);
  ASSERT_NE(a_ident_id, 0);

  auto sum_expr_id = node_id_map.GetId(sum_expr);
  ASSERT_NE(sum_expr_id, 0);

  auto e_var_id = node_id_map.GetId(e_var);
  ASSERT_NE(e_var_id, 0);

  auto vec_member_access_id = node_id_map.GetId(
      e_var->constructor->As<ast::MemberAccessorExpression>()->member);
  ASSERT_NE(vec_member_access_id, 0);

  // use_id is invalid.
  EXPECT_FALSE(MutationReplaceIdentifier(0, a_var_id)
                   .IsApplicable(program, node_id_map));

  // use_id is not an identifier expression.
  EXPECT_FALSE(MutationReplaceIdentifier(sum_expr_id, a_var_id)
                   .IsApplicable(program, node_id_map));

  // use_id is an identifier but not a variable user.
  EXPECT_FALSE(MutationReplaceIdentifier(vec_member_access_id, a_var_id)
                   .IsApplicable(program, node_id_map));

  // replacement_id is invalid.
  EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, 0)
                   .IsApplicable(program, node_id_map));

  // replacement_id is not a variable.
  EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, sum_expr_id)
                   .IsApplicable(program, node_id_map));

  // Can't replace a variable with itself.
  EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, a_var_id)
                   .IsApplicable(program, node_id_map));

  // Replacement is not in scope.
  EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, b_var_id)
                   .IsApplicable(program, node_id_map));
  EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, e_var_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, GlobalVarNotInScope) {
  // Can't use the global variable if it's not in scope.
  std::string shader = R"(
var<private> a: i32;

fn f() {
  a = 3;
}

var<private> b: i32;
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs);
  ASSERT_NE(use_id, 0);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
  ASSERT_NE(replacement_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable1) {
  // Can't replace `a` with `b` since the store type is wrong (the same storage
  // class though).
  std::string shader = R"(
var<private> a: i32;
var<private> b: u32;
fn f() {
  *&a = 4;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable2) {
  // Can't replace `a` with `b` since the store type is wrong (the storage
  // class is different though).
  std::string shader = R"(
var<private> a: i32;
fn f() {
  var b: u32;
  *&a = 4;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST()
                                              .Functions()[0]
                                              ->body->statements[0]
                                              ->As<ast::VariableDeclStatement>()
                                              ->variable);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[1]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable3) {
  // Can't replace `a` with `b` since the latter is not a reference (the store
  // type is the same, though).
  std::string shader = R"(
var<private> a: i32;
fn f() {
  let b = 45;
  *&a = 4;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST()
                                              .Functions()[0]
                                              ->body->statements[0]
                                              ->As<ast::VariableDeclStatement>()
                                              ->variable);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[1]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable4) {
  // Can't replace `a` with `b` since the latter is not a reference (the store
  // type is the same, though).
  std::string shader = R"(
var<private> a: i32;
fn f(b: i32) {
  *&a = 4;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id =
      node_id_map.GetId(program.AST().Functions()[0]->params[0]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable5) {
  // Can't replace `a` with `b` since the latter has a wrong access mode
  // (`read` for uniform storage class).
  std::string shader = R"(
struct S {
  a: i32;
};

var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
  *&a = S(4);
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable6) {
  // Can't replace `ptr_b` with `a` since the latter is not a pointer.
  std::string shader = R"(
struct S {
  a: i32;
};

var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
  let ptr_b = &b;
  *&a = *ptr_b;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[1]
                                      ->As<ast::AssignmentStatement>()
                                      ->rhs->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable8) {
  // Can't replace `ptr_b` with `c` since the latter has a wrong access mode and
  // storage class.
  std::string shader = R"(
struct S {
  a: i32;
};

var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
@group(1) @binding(2) var<storage, write> c: S;
fn f() {
  let ptr_b = &b;
  *&a = *ptr_b;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[2]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[1]
                                      ->As<ast::AssignmentStatement>()
                                      ->rhs->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable9) {
  // Can't replace `b` with `e` since the latter is not a reference.
  std::string shader = R"(
struct S {
  a: i32;
};

var<private> a: S;
let e = 3;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
  *&a = *&b;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->rhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable10) {
  // Can't replace `b` with `e` since the latter has a wrong access mode.
  std::string shader = R"(
struct S {
  a: i32;
};

var<private> a: S;
@group(0) @binding(0) var<storage, write> e: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
  *&a = *&b;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
  ASSERT_NE(replacement_id, 0);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[0]
                                      ->As<ast::AssignmentStatement>()
                                      ->rhs->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, Applicable1) {
  // Can replace `a` with `b` (same storage class).
  std::string shader = R"(
fn f() {
  var b : vec2<u32>;
  var a = vec2<u32>(34u, 45u);
  (*&a)[1] = 3u;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[2]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::IndexAccessorExpression>()
                                      ->object->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  auto replacement_id = node_id_map.GetId(program.AST()
                                              .Functions()[0]
                                              ->body->statements[0]
                                              ->As<ast::VariableDeclStatement>()
                                              ->variable);
  ASSERT_NE(replacement_id, 0);

  ASSERT_TRUE(MaybeApplyMutation(
      program, MutationReplaceIdentifier(use_id, replacement_id), node_id_map,
      &program, &node_id_map, nullptr));
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  writer::wgsl::Options options;
  auto result = writer::wgsl::Generate(&program, options);
  ASSERT_TRUE(result.success) << result.error;

  std::string expected_shader = R"(fn f() {
  var b : vec2<u32>;
  var a = vec2<u32>(34u, 45u);
  (*(&(b)))[1] = 3u;
}
)";
  ASSERT_EQ(expected_shader, result.wgsl);
}

TEST(ReplaceIdentifierTest, Applicable2) {
  // Can replace `ptr_a` with `b` - the function parameter.
  std::string shader = R"(
fn f(b: ptr<function, vec2<u32>>) {
  var a = vec2<u32>(34u, 45u);
  let ptr_a = &a;
  (*ptr_a)[1] = 3u;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[2]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::IndexAccessorExpression>()
                                      ->object->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  auto replacement_id =
      node_id_map.GetId(program.AST().Functions()[0]->params[0]);
  ASSERT_NE(replacement_id, 0);

  ASSERT_TRUE(MaybeApplyMutation(
      program, MutationReplaceIdentifier(use_id, replacement_id), node_id_map,
      &program, &node_id_map, nullptr));
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  writer::wgsl::Options options;
  auto result = writer::wgsl::Generate(&program, options);
  ASSERT_TRUE(result.success) << result.error;

  std::string expected_shader = R"(fn f(b : ptr<function, vec2<u32>>) {
  var a = vec2<u32>(34u, 45u);
  let ptr_a = &(a);
  (*(b))[1] = 3u;
}
)";
  ASSERT_EQ(expected_shader, result.wgsl);
}

TEST(ReplaceIdentifierTest, NotApplicable12) {
  // Can't replace `a` with `b` (both are references with different storage
  // class).
  std::string shader = R"(
var<private> b : vec2<u32>;
fn f() {
  var a = vec2<u32>(34u, 45u);
  (*&a)[1] = 3u;
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(program.AST()
                                      .Functions()[0]
                                      ->body->statements[1]
                                      ->As<ast::AssignmentStatement>()
                                      ->lhs->As<ast::IndexAccessorExpression>()
                                      ->object->As<ast::UnaryOpExpression>()
                                      ->expr->As<ast::UnaryOpExpression>()
                                      ->expr);
  ASSERT_NE(use_id, 0);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
  ASSERT_NE(replacement_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable13) {
  // Can't replace `a` with `b` (both are references with different storage
  // class).
  std::string shader = R"(
var<private> b : vec2<u32>;
fn f() {
  var a = vec2<u32>(34u, 45u);
  let c = (*&a)[1];
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(
      program.AST()
          .Functions()[0]
          ->body->statements[1]
          ->As<ast::VariableDeclStatement>()
          ->variable->constructor->As<ast::IndexAccessorExpression>()
          ->object->As<ast::UnaryOpExpression>()
          ->expr->As<ast::UnaryOpExpression>()
          ->expr);
  ASSERT_NE(use_id, 0);

  auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
  ASSERT_NE(replacement_id, 0);

  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

TEST(ReplaceIdentifierTest, NotApplicable14) {
  // Can't replace `ptr_a` with `ptr_b` (both are pointers with different
  // storage class).
  std::string shader = R"(
var<private> b: vec2<u32>;
fn f() {
  var a = vec2<u32>(34u, 45u);
  let ptr_a = &a;
  let ptr_b = &b;
  let c = (*ptr_a)[1];
}
)";
  Source::File file("test.wgsl", shader);
  auto program = reader::wgsl::Parse(&file);
  ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();

  NodeIdMap node_id_map(program);

  auto use_id = node_id_map.GetId(
      program.AST()
          .Functions()[0]
          ->body->statements[3]
          ->As<ast::VariableDeclStatement>()
          ->variable->constructor->As<ast::IndexAccessorExpression>()
          ->object->As<ast::UnaryOpExpression>()
          ->expr);
  ASSERT_NE(use_id, 0);

  auto replacement_id = node_id_map.GetId(program.AST()
                                              .Functions()[0]
                                              ->body->statements[2]
                                              ->As<ast::VariableDeclStatement>()
                                              ->variable);
  ASSERT_NE(replacement_id, 0);
  ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
                   .IsApplicable(program, node_id_map));
}

}  // namespace
}  // namespace ast_fuzzer
}  // namespace fuzzers
}  // namespace tint
