// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/lang/core/ir/transform/block_decorated_structs.h"

#include <utility>

#include "src/tint/lang/core/ir/transform/helper_test.h"
#include "src/tint/lang/core/type/array.h"
#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/core/type/struct.h"

namespace tint::core::ir::transform {
namespace {

using namespace tint::core::fluent_types;     // NOLINT
using namespace tint::core::number_suffixes;  // NOLINT

using IR_BlockDecoratedStructsTest = TransformTest;

TEST_F(IR_BlockDecoratedStructsTest, NoRootBlock) {
    auto* func = b.Function("foo", ty.void_());
    func->Block()->Append(b.Return(func));

    auto* expect = R"(
%foo = func():void {
  $B1: {
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, Scalar_Uniform) {
    auto* buffer = b.Var(ty.ptr<uniform, i32>());
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* func = b.Function("foo", ty.i32());

    auto* block = func->Block();
    auto* load = block->Append(b.Load(buffer));
    block->Append(b.Return(func, load));

    auto* expect = R"(
tint_symbol_1 = struct @align(4), @block {
  tint_symbol:i32 @offset(0)
}

$B1: {  # root
  %1:ptr<uniform, tint_symbol_1, read> = var @binding_point(0, 0)
}

%foo = func():i32 {
  $B2: {
    %3:ptr<uniform, i32, read> = access %1, 0u
    %4:i32 = load %3
    ret %4
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, Scalar_Storage) {
    auto* buffer = b.Var(ty.ptr<storage, i32>());
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* func = b.Function("foo", ty.void_());
    func->Block()->Append(b.Store(buffer, 42_i));
    func->Block()->Append(b.Return(func));

    auto* expect = R"(
tint_symbol_1 = struct @align(4), @block {
  tint_symbol:i32 @offset(0)
}

$B1: {  # root
  %1:ptr<storage, tint_symbol_1, read_write> = var @binding_point(0, 0)
}

%foo = func():void {
  $B2: {
    %3:ptr<storage, i32, read_write> = access %1, 0u
    store %3, 42i
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, Scalar_PushConstant) {
    auto* buffer = b.Var(ty.ptr<push_constant, i32>());
    mod.root_block->Append(buffer);

    auto* func = b.Function("foo", ty.i32());
    b.Append(func->Block(), [&] {  //
        b.Return(func, b.Load(buffer));
    });

    auto* expect = R"(
tint_symbol_1 = struct @align(4), @block {
  tint_symbol:i32 @offset(0)
}

$B1: {  # root
  %1:ptr<push_constant, tint_symbol_1, read> = var
}

%foo = func():i32 {
  $B2: {
    %3:ptr<push_constant, i32, read> = access %1, 0u
    %4:i32 = load %3
    ret %4
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, RuntimeArray) {
    auto* buffer = b.Var(ty.ptr<storage, array<i32>>());
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* func = b.Function("foo", ty.void_());

    b.Append(func->Block(), [&] {
        auto* access = b.Access(ty.ptr<storage, i32>(), buffer, 1_u);
        b.Store(access, 42_i);
        b.Return(func);
    });

    auto* expect = R"(
tint_symbol_1 = struct @align(4), @block {
  tint_symbol:array<i32> @offset(0)
}

$B1: {  # root
  %1:ptr<storage, tint_symbol_1, read_write> = var @binding_point(0, 0)
}

%foo = func():void {
  $B2: {
    %3:ptr<storage, array<i32>, read_write> = access %1, 0u
    %4:ptr<storage, i32, read_write> = access %3, 1u
    store %4, 42i
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, RuntimeArray_InStruct) {
    auto* structure =
        ty.Struct(mod.symbols.New("MyStruct"), {
                                                   {mod.symbols.New("i"), ty.i32()},
                                                   {mod.symbols.New("arr"), ty.array<i32>()},
                                               });

    auto* buffer = b.Var(ty.ptr(storage, structure, core::Access::kReadWrite));
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* i32_ptr = ty.ptr<storage, i32>();

    auto* func = b.Function("foo", ty.void_());

    b.Append(func->Block(), [&] {
        auto* val_ptr = b.Access(i32_ptr, buffer, 0_u);
        auto* load = b.Load(val_ptr);
        auto* elem_ptr = b.Access(i32_ptr, buffer, 1_u, 3_u);
        b.Store(elem_ptr, load);
        b.Return(func);
    });

    auto* expect = R"(
MyStruct = struct @align(4), @block {
  i:i32 @offset(0)
  arr:array<i32> @offset(4)
}

$B1: {  # root
  %1:ptr<storage, MyStruct, read_write> = var @binding_point(0, 0)
}

%foo = func():void {
  $B2: {
    %3:ptr<storage, i32, read_write> = access %1, 0u
    %4:i32 = load %3
    %5:ptr<storage, i32, read_write> = access %1, 1u, 3u
    store %5, %4
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, RuntimeArray_InStruct_ArrayLengthViaLets) {
    auto* structure =
        ty.Struct(mod.symbols.New("MyStruct"), {
                                                   {mod.symbols.New("i"), ty.i32()},
                                                   {mod.symbols.New("arr"), ty.array<i32>()},
                                               });

    auto* buffer = b.Var(ty.ptr(storage, structure, core::Access::kReadWrite));
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* func = b.Function("foo", ty.u32());
    b.Append(func->Block(), [&] {
        auto* let_root = b.Let("root", buffer->Result(0));
        auto* let_arr = b.Let("arr", b.Access(ty.ptr(storage, ty.array<i32>()), let_root, 1_u));
        auto* length = b.Call(ty.u32(), core::BuiltinFn::kArrayLength, let_arr);
        b.Return(func, length);
    });

    auto* expect = R"(
MyStruct = struct @align(4), @block {
  i:i32 @offset(0)
  arr:array<i32> @offset(4)
}

$B1: {  # root
  %1:ptr<storage, MyStruct, read_write> = var @binding_point(0, 0)
}

%foo = func():u32 {
  $B2: {
    %root:ptr<storage, MyStruct, read_write> = let %1
    %4:ptr<storage, array<i32>, read_write> = access %root, 1u
    %arr:ptr<storage, array<i32>, read_write> = let %4
    %6:u32 = arrayLength %arr
    ret %6
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, StructUsedElsewhere) {
    auto* structure = ty.Struct(mod.symbols.New("MyStruct"), {
                                                                 {mod.symbols.New("a"), ty.i32()},
                                                                 {mod.symbols.New("b"), ty.i32()},
                                                             });

    auto* buffer = b.Var(ty.ptr(storage, structure, core::Access::kReadWrite));
    buffer->SetBindingPoint(0, 0);
    mod.root_block->Append(buffer);

    auto* private_var = b.Var(ty.ptr<private_, read_write>(structure));
    mod.root_block->Append(private_var);

    auto* func = b.Function("foo", ty.void_());
    auto* load = func->Block()->Append(b.Load(private_var));
    func->Block()->Append(b.Store(buffer, load));
    func->Block()->Append(b.Return(func));

    auto* expect = R"(
MyStruct = struct @align(4) {
  a:i32 @offset(0)
  b:i32 @offset(4)
}

tint_symbol_1 = struct @align(4), @block {
  tint_symbol:MyStruct @offset(0)
}

$B1: {  # root
  %1:ptr<storage, tint_symbol_1, read_write> = var @binding_point(0, 0)
  %2:ptr<private, MyStruct, read_write> = var
}

%foo = func():void {
  $B2: {
    %4:MyStruct = load %2
    %5:ptr<storage, MyStruct, read_write> = access %1, 0u
    store %5, %4
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

TEST_F(IR_BlockDecoratedStructsTest, MultipleBuffers) {
    auto* buffer_a = b.Var(ty.ptr<storage, i32>());
    auto* buffer_b = b.Var(ty.ptr<storage, i32>());
    auto* buffer_c = b.Var(ty.ptr<storage, i32>());
    buffer_a->SetBindingPoint(0, 0);
    buffer_b->SetBindingPoint(0, 1);
    buffer_c->SetBindingPoint(0, 2);
    auto* root = mod.root_block.Get();
    root->Append(buffer_a);
    root->Append(buffer_b);
    root->Append(buffer_c);

    auto* func = b.Function("foo", ty.void_());
    b.Append(func->Block(), [&] {
        auto* load_b = b.Load(buffer_b);
        auto* load_c = b.Load(buffer_c);
        b.Store(buffer_a, b.Add(ty.i32(), load_b, load_c));
        b.Return(func);
    });

    auto* expect = R"(
tint_symbol_1 = struct @align(4), @block {
  tint_symbol:i32 @offset(0)
}

tint_symbol_3 = struct @align(4), @block {
  tint_symbol_2:i32 @offset(0)
}

tint_symbol_5 = struct @align(4), @block {
  tint_symbol_4:i32 @offset(0)
}

$B1: {  # root
  %1:ptr<storage, tint_symbol_1, read_write> = var @binding_point(0, 0)
  %2:ptr<storage, tint_symbol_3, read_write> = var @binding_point(0, 1)
  %3:ptr<storage, tint_symbol_5, read_write> = var @binding_point(0, 2)
}

%foo = func():void {
  $B2: {
    %5:ptr<storage, i32, read_write> = access %2, 0u
    %6:i32 = load %5
    %7:ptr<storage, i32, read_write> = access %3, 0u
    %8:i32 = load %7
    %9:i32 = add %6, %8
    %10:ptr<storage, i32, read_write> = access %1, 0u
    store %10, %9
    ret
  }
}
)";

    Run(BlockDecoratedStructs);

    EXPECT_EQ(expect, str());
}

}  // namespace
}  // namespace tint::core::ir::transform
