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

#include "src/tint/transform/test_helper.h"
#include "src/tint/transform/unshadow.h"

namespace tint::transform {
namespace {

using SimplifyPointersTest = TransformTest;

TEST_F(SimplifyPointersTest, EmptyModule) {
  auto* src = "";
  auto* expect = "";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, FoldPointer) {
  auto* src = R"(
fn f() {
  var v : i32;
  let p : ptr<function, i32> = &v;
  let x : i32 = *p;
}
)";

  auto* expect = R"(
fn f() {
  var v : i32;
  let x : i32 = v;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, AddressOfDeref) {
  auto* src = R"(
fn f() {
  var v : i32;
  let p : ptr<function, i32> = &(v);
  let x : ptr<function, i32> = &(*(p));
  let y : ptr<function, i32> = &(*(&(*(p))));
  let z : ptr<function, i32> = &(*(&(*(&(*(&(*(p))))))));
  var a = *x;
  var b = *y;
  var c = *z;
}
)";

  auto* expect = R"(
fn f() {
  var v : i32;
  var a = v;
  var b = v;
  var c = v;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, DerefAddressOf) {
  auto* src = R"(
fn f() {
  var v : i32;
  let x : i32 = *(&(v));
  let y : i32 = *(&(*(&(v))));
  let z : i32 = *(&(*(&(*(&(*(&(v))))))));
}
)";

  auto* expect = R"(
fn f() {
  var v : i32;
  let x : i32 = v;
  let y : i32 = v;
  let z : i32 = v;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, ComplexChain) {
  auto* src = R"(
fn f() {
  var a : array<mat4x4<f32>, 4>;
  let ap : ptr<function, array<mat4x4<f32>, 4>> = &a;
  let mp : ptr<function, mat4x4<f32>> = &(*ap)[3];
  let vp : ptr<function, vec4<f32>> = &(*mp)[2];
  let v : vec4<f32> = *vp;
}
)";

  auto* expect = R"(
fn f() {
  var a : array<mat4x4<f32>, 4>;
  let v : vec4<f32> = a[3][2];
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, SavedVars) {
  auto* src = R"(
struct S {
  i : i32,
};

fn arr() {
  var a : array<S, 2>;
  var i : i32 = 0;
  var j : i32 = 0;
  let p : ptr<function, i32> = &a[i + j].i;
  i = 2;
  *p = 4;
}

fn matrix() {
  var m : mat3x3<f32>;
  var i : i32 = 0;
  var j : i32 = 0;
  let p : ptr<function, vec3<f32>> = &m[i + j];
  i = 2;
  *p = vec3<f32>(4.0, 5.0, 6.0);
}
)";

  auto* expect = R"(
struct S {
  i : i32,
}

fn arr() {
  var a : array<S, 2>;
  var i : i32 = 0;
  var j : i32 = 0;
  let p_save = (i + j);
  i = 2;
  a[p_save].i = 4;
}

fn matrix() {
  var m : mat3x3<f32>;
  var i : i32 = 0;
  var j : i32 = 0;
  let p_save_1 = (i + j);
  i = 2;
  m[p_save_1] = vec3<f32>(4.0, 5.0, 6.0);
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, DontSaveLiterals) {
  auto* src = R"(
fn f() {
  var arr : array<i32, 2>;
  let p1 : ptr<function, i32> = &arr[1];
  *p1 = 4;
}
)";

  auto* expect = R"(
fn f() {
  var arr : array<i32, 2>;
  arr[1] = 4;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, SavedVarsChain) {
  auto* src = R"(
fn f() {
  var arr : array<array<i32, 2>, 2>;
  let i : i32 = 0;
  let j : i32 = 1;
  let p : ptr<function, array<i32, 2>> = &arr[i];
  let q : ptr<function, i32> = &(*p)[j];
  *q = 12;
}
)";

  auto* expect = R"(
fn f() {
  var arr : array<array<i32, 2>, 2>;
  let i : i32 = 0;
  let j : i32 = 1;
  let p_save = i;
  let q_save = j;
  arr[p_save][q_save] = 12;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, ForLoopInit) {
  auto* src = R"(
fn foo() -> i32 {
  return 1;
}

@stage(fragment)
fn main() {
  var arr = array<f32, 4>();
  for (let a = &arr[foo()]; ;) {
    let x = *a;
    break;
  }
}
)";

  auto* expect = R"(
fn foo() -> i32 {
  return 1;
}

@stage(fragment)
fn main() {
  var arr = array<f32, 4>();
  let a_save = foo();
  for(; ; ) {
    let x = arr[a_save];
    break;
  }
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, MultiSavedVarsInSinglePtrLetExpr) {
  auto* src = R"(
fn x() -> i32 {
  return 1;
}

fn y() -> i32 {
  return 1;
}

fn z() -> i32 {
  return 1;
}

struct Inner {
  a : array<i32, 2>,
};

struct Outer {
  a : array<Inner, 2>,
};

fn f() {
  var arr : array<Outer, 2>;
  let p : ptr<function, i32> = &arr[x()].a[y()].a[z()];
  *p = 1;
  *p = 2;
}
)";

  auto* expect = R"(
fn x() -> i32 {
  return 1;
}

fn y() -> i32 {
  return 1;
}

fn z() -> i32 {
  return 1;
}

struct Inner {
  a : array<i32, 2>,
}

struct Outer {
  a : array<Inner, 2>,
}

fn f() {
  var arr : array<Outer, 2>;
  let p_save = x();
  let p_save_1 = y();
  let p_save_2 = z();
  arr[p_save].a[p_save_1].a[p_save_2] = 1;
  arr[p_save].a[p_save_1].a[p_save_2] = 2;
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

TEST_F(SimplifyPointersTest, ShadowPointer) {
  auto* src = R"(
var<private> a : array<i32, 2>;

@stage(compute) @workgroup_size(1)
fn main() {
  let x = &a;
  var a : i32 = (*x)[0];
  {
    var a : i32 = (*x)[1];
  }
}
)";

  auto* expect = R"(
var<private> a : array<i32, 2>;

@stage(compute) @workgroup_size(1)
fn main() {
  var a_1 : i32 = a[0];
  {
    var a_2 : i32 = a[1];
  }
}
)";

  auto got = Run<Unshadow, SimplifyPointers>(src);

  EXPECT_EQ(expect, str(got));
}

}  // namespace
}  // namespace tint::transform
