// 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 "fuzzers/tint_ast_fuzzer/mt_rng.h"
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "fuzzers/tint_ast_fuzzer/mutator.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"

#include "fuzzers/tint_ast_fuzzer/node_id_map.h"

#include "src/ast/call_statement.h"
#include "src/program_builder.h"
#include "src/reader/wgsl/parser.h"
#include "src/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"(
[[block]]
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"(
[[block]]
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"(
[[block]]
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"(
[[block]]
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"(
[[block]]
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::ArrayAccessorExpression>()
                                      ->array()
                                      ->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::ArrayAccessorExpression>()
                                      ->array()
                                      ->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::ArrayAccessorExpression>()
                                      ->array()
                                      ->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::ArrayAccessorExpression>()
                                      ->array()
                                      ->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::ArrayAccessorExpression>()
                                      ->array()
                                      ->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
