// 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/ast/struct_block_decoration.h"
#include "src/resolver/resolver.h"
#include "src/resolver/resolver_test_helper.h"

#include "gmock/gmock.h"

namespace tint {
namespace resolver {
namespace {

// Helpers and typedefs
template <typename T>
using DataType = builder::DataType<T>;
template <typename T>
using vec2 = builder::vec2<T>;
template <typename T>
using vec3 = builder::vec3<T>;
template <typename T>
using vec4 = builder::vec4<T>;
template <typename T>
using mat2x2 = builder::mat2x2<T>;
template <typename T>
using mat3x3 = builder::mat3x3<T>;
template <typename T>
using mat4x4 = builder::mat4x4<T>;
template <typename T>
using alias = builder::alias<T>;
using f32 = builder::f32;
using i32 = builder::i32;
using u32 = builder::u32;

struct ResolverInferredTypeTest : public resolver::TestHelper,
                                  public testing::Test {};

struct Params {
  builder::ast_expr_func_ptr create_value;
  builder::sem_type_func_ptr create_expected_type;
};

template <typename T>
constexpr Params ParamsFor() {
  return Params{DataType<T>::Expr, DataType<T>::Sem};
}

Params all_cases[] = {
    ParamsFor<bool>(),                //
    ParamsFor<u32>(),                 //
    ParamsFor<i32>(),                 //
    ParamsFor<f32>(),                 //
    ParamsFor<vec3<bool>>(),          //
    ParamsFor<vec3<i32>>(),           //
    ParamsFor<vec3<u32>>(),           //
    ParamsFor<vec3<f32>>(),           //
    ParamsFor<mat3x3<f32>>(),         //
    ParamsFor<alias<bool>>(),         //
    ParamsFor<alias<u32>>(),          //
    ParamsFor<alias<i32>>(),          //
    ParamsFor<alias<f32>>(),          //
    ParamsFor<alias<vec3<bool>>>(),   //
    ParamsFor<alias<vec3<i32>>>(),    //
    ParamsFor<alias<vec3<u32>>>(),    //
    ParamsFor<alias<vec3<f32>>>(),    //
    ParamsFor<alias<mat3x3<f32>>>(),  //
};

using ResolverInferredTypeParamTest = ResolverTestWithParam<Params>;

TEST_P(ResolverInferredTypeParamTest, GlobalLet_Pass) {
  auto& params = GetParam();

  auto* expected_type = params.create_expected_type(*this);

  // let a = <type constructor>;
  auto* ctor_expr = params.create_value(*this, 0);
  auto* var = GlobalConst("a", nullptr, ctor_expr);
  WrapInFunction();

  EXPECT_TRUE(r()->Resolve()) << r()->error();
  EXPECT_EQ(TypeOf(var), expected_type);
}

TEST_P(ResolverInferredTypeParamTest, GlobalVar_Fail) {
  auto& params = GetParam();

  // var a = <type constructor>;
  auto* ctor_expr = params.create_value(*this, 0);
  Global(Source{{12, 34}}, "a", nullptr, ast::StorageClass::kPrivate,
         ctor_expr);
  WrapInFunction();

  EXPECT_FALSE(r()->Resolve());
  EXPECT_EQ(r()->error(),
            "12:34 error: global var declaration must specify a type");
}

TEST_P(ResolverInferredTypeParamTest, LocalLet_Pass) {
  auto& params = GetParam();

  auto* expected_type = params.create_expected_type(*this);

  // let a = <type constructor>;
  auto* ctor_expr = params.create_value(*this, 0);
  auto* var = Const("a", nullptr, ctor_expr);
  WrapInFunction(var);

  EXPECT_TRUE(r()->Resolve()) << r()->error();
  EXPECT_EQ(TypeOf(var), expected_type);
}

TEST_P(ResolverInferredTypeParamTest, LocalVar_Pass) {
  auto& params = GetParam();

  auto* expected_type = params.create_expected_type(*this);

  // var a = <type constructor>;
  auto* ctor_expr = params.create_value(*this, 0);
  auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
  WrapInFunction(var);

  EXPECT_TRUE(r()->Resolve()) << r()->error();
  EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
}

INSTANTIATE_TEST_SUITE_P(ResolverTest,
                         ResolverInferredTypeParamTest,
                         testing::ValuesIn(all_cases));

TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
  auto* type = ty.array(ty.u32(), 10);
  auto* expected_type =
      create<sem::Array>(create<sem::U32>(), 10, 4, 4 * 10, 4, 4);

  auto* ctor_expr = Construct(type);
  auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
  WrapInFunction(var);

  EXPECT_TRUE(r()->Resolve()) << r()->error();
  EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
}

TEST_F(ResolverInferredTypeTest, InferStruct_Pass) {
  auto* member = Member("x", ty.i32());
  auto* str = Structure("S", {member}, {create<ast::StructBlockDecoration>()});

  auto* expected_type = create<sem::Struct>(
      str, str->name(),
      sem::StructMemberList{create<sem::StructMember>(
          member, member->symbol(), create<sem::I32>(), 0, 0, 0, 4)},
      0, 4, 4);

  auto* ctor_expr = Construct(ty.Of(str));

  auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
  WrapInFunction(var);

  EXPECT_TRUE(r()->Resolve()) << r()->error();
  EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
}

}  // namespace
}  // namespace resolver
}  // namespace tint
