// Copyright 2020 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/first_index_offset.h"

#include <memory>
#include <utility>
#include <vector>

#include "src/transform/test_helper.h"

namespace tint {
namespace transform {
namespace {

using FirstIndexOffsetTest = TransformTest;

TEST_F(FirstIndexOffsetTest, Error_AlreadyTransformed) {
  auto* src = R"(
[[builtin(vertex_idx)]] var<in> vert_idx : u32;

fn test() -> u32 {
  return vert_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto* expect = R"(manager().Run() errored:
error: First index offset transform has already been applied.)";

  std::vector<std::unique_ptr<transform::Transform>> transforms;
  transforms.emplace_back(std::make_unique<FirstIndexOffset>(0, 0));
  transforms.emplace_back(std::make_unique<FirstIndexOffset>(1, 1));

  auto got = Transform(src, std::move(transforms));

  EXPECT_EQ(expect, got);
}

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

  auto got = Transform<FirstIndexOffset>(src, 0, 0);

  EXPECT_EQ(expect, got);
}

TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
  auto* src = R"(
[[builtin(vertex_idx)]] var<in> vert_idx : u32;

fn test() -> u32 {
  return vert_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto* expect = R"(
[[block]]
struct TintFirstIndexOffsetData {
  [[offset(0)]]
  tint_first_vertex_index : u32;
};

[[builtin(vertex_idx)]] var<in> tint_first_index_offset_vert_idx : u32;
[[binding(1), set(2)]] var<uniform> tint_first_index_data : TintFirstIndexOffsetData;

fn test() -> u32 {
  const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
  return vert_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto got = Transform<FirstIndexOffset>(src, 1, 2);

  EXPECT_EQ(expect, got);
}

TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
  auto* src = R"(
[[builtin(instance_idx)]] var<in> inst_idx : u32;

fn test() -> u32 {
  return inst_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto* expect = R"(
[[block]]
struct TintFirstIndexOffsetData {
  [[offset(0)]]
  tint_first_instance_index : u32;
};

[[builtin(instance_idx)]] var<in> tint_first_index_offset_inst_idx : u32;
[[binding(1), set(7)]] var<uniform> tint_first_index_data : TintFirstIndexOffsetData;

fn test() -> u32 {
  const inst_idx : u32 = (tint_first_index_offset_inst_idx + tint_first_index_data.tint_first_instance_index);
  return inst_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto got = Transform<FirstIndexOffset>(src, 1, 7);

  EXPECT_EQ(expect, got);
}

TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
  auto* src = R"(
[[builtin(instance_idx)]] var<in> instance_idx : u32;
[[builtin(vertex_idx)]] var<in> vert_idx : u32;

fn test() -> u32 {
  return instance_idx + vert_idx;
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto* expect = R"(
[[block]]
struct TintFirstIndexOffsetData {
  [[offset(0)]]
  tint_first_vertex_index : u32;
  [[offset(4)]]
  tint_first_instance_index : u32;
};

[[builtin(instance_idx)]] var<in> tint_first_index_offset_instance_idx : u32;
[[builtin(vertex_idx)]] var<in> tint_first_index_offset_vert_idx : u32;
[[binding(1), set(2)]] var<uniform> tint_first_index_data : TintFirstIndexOffsetData;

fn test() -> u32 {
  const instance_idx : u32 = (tint_first_index_offset_instance_idx + tint_first_index_data.tint_first_instance_index);
  const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
  return (instance_idx + vert_idx);
}

[[stage(vertex)]]
fn entry() -> void {
  test();
}
)";

  auto got = Transform<FirstIndexOffset>(src, 1, 2);

  EXPECT_EQ(expect, got);
}

TEST_F(FirstIndexOffsetTest, NestedCalls) {
  auto* src = R"(
[[builtin(vertex_idx)]] var<in> vert_idx : u32;

fn func1() -> u32 {
  return vert_idx;
}

fn func2() -> u32 {
  return func1();
}

[[stage(vertex)]]
fn entry() -> void {
  func2();
}
)";

  auto* expect = R"(
[[block]]
struct TintFirstIndexOffsetData {
  [[offset(0)]]
  tint_first_vertex_index : u32;
};

[[builtin(vertex_idx)]] var<in> tint_first_index_offset_vert_idx : u32;
[[binding(1), set(2)]] var<uniform> tint_first_index_data : TintFirstIndexOffsetData;

fn func1() -> u32 {
  const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
  return vert_idx;
}

fn func2() -> u32 {
  return func1();
}

[[stage(vertex)]]
fn entry() -> void {
  func2();
}
)";

  auto got = Transform<FirstIndexOffset>(src, 1, 2);

  EXPECT_EQ(expect, got);
}

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