// 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 <memory>
#include <string>
#include <vector>

#include "src/ast/call_expression.h"
#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
#include "src/ast/type/vector_type.h"
#include "src/ast/type_constructor_expression.h"
#include "src/type_determiner.h"
#include "src/writer/hlsl/test_helper.h"

namespace tint {
namespace writer {
namespace hlsl {
namespace {

using HlslGeneratorImplTest_Import = TestHelper;

struct HlslImportData {
  const char* name;
  const char* hlsl_name;
};
inline std::ostream& operator<<(std::ostream& out, HlslImportData data) {
  out << data.name;
  return out;
}

using HlslImportData_SingleParamTest = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_SingleParamTest, FloatScalar) {
  auto param = GetParam();

  ast::type::F32 f32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 1.f)));

  auto* ident = create<ast::IdentifierExpression>(
      mod.RegisterSymbol(param.name), param.name);
  ast::CallExpression expr(ident, params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f)");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_SingleParamTest,
                         testing::Values(HlslImportData{"abs", "abs"},
                                         HlslImportData{"acos", "acos"},
                                         HlslImportData{"asin", "asin"},
                                         HlslImportData{"atan", "atan"},
                                         HlslImportData{"cos", "cos"},
                                         HlslImportData{"cosh", "cosh"},
                                         HlslImportData{"ceil", "ceil"},
                                         HlslImportData{"exp", "exp"},
                                         HlslImportData{"exp2", "exp2"},
                                         HlslImportData{"floor", "floor"},
                                         HlslImportData{"fract", "frac"},
                                         HlslImportData{"inverseSqrt", "rsqrt"},
                                         HlslImportData{"length", "length"},
                                         HlslImportData{"log", "log"},
                                         HlslImportData{"log2", "log2"},
                                         HlslImportData{"normalize",
                                                        "normalize"},
                                         HlslImportData{"round", "round"},
                                         HlslImportData{"sign", "sign"},
                                         HlslImportData{"sin", "sin"},
                                         HlslImportData{"sinh", "sinh"},
                                         HlslImportData{"sqrt", "sqrt"},
                                         HlslImportData{"tan", "tan"},
                                         HlslImportData{"tanh", "tanh"},
                                         HlslImportData{"trunc", "trunc"}));

using HlslImportData_SingleIntParamTest = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_SingleIntParamTest, IntScalar) {
  auto param = GetParam();

  ast::type::I32 i32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 1)));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1)");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_SingleIntParamTest,
                         testing::Values(HlslImportData{"abs", "abs"}));

using HlslImportData_DualParamTest = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_DualParamTest, FloatScalar) {
  auto param = GetParam();

  ast::type::F32 f32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 1.f)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 2.f)));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f, 2.0f)");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_DualParamTest,
                         testing::Values(HlslImportData{"atan2", "atan2"},
                                         HlslImportData{"distance", "distance"},
                                         HlslImportData{"max", "max"},
                                         HlslImportData{"min", "min"},
                                         HlslImportData{"pow", "pow"},
                                         HlslImportData{"reflect", "reflect"},
                                         HlslImportData{"step", "step"}));

using HlslImportData_DualParam_VectorTest = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_DualParam_VectorTest, FloatVector) {
  auto param = GetParam();

  ast::type::F32 f32;
  ast::type::Vector vec(&f32, 3);

  ast::ExpressionList params;
  params.push_back(create<ast::TypeConstructorExpression>(
      &vec, ast::ExpressionList{
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 1.f)),
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 2.f)),
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 3.f)),
            }));

  params.push_back(create<ast::TypeConstructorExpression>(
      &vec, ast::ExpressionList{
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 4.f)),
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 5.f)),
                create<ast::ScalarConstructorExpression>(
                    create<ast::FloatLiteral>(&f32, 6.f)),
            }));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(),
            std::string(param.hlsl_name) +
                "(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f))");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_DualParam_VectorTest,
                         testing::Values(HlslImportData{"cross", "cross"}));

using HlslImportData_DualParam_Int_Test = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_DualParam_Int_Test, IntScalar) {
  auto param = GetParam();

  ast::type::I32 i32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 1)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 2)));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1, 2)");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_DualParam_Int_Test,
                         testing::Values(HlslImportData{"max", "max"},
                                         HlslImportData{"min", "min"}));

using HlslImportData_TripleParamTest = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_TripleParamTest, FloatScalar) {
  auto param = GetParam();

  ast::type::F32 f32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 1.f)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 2.f)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::FloatLiteral>(&f32, 3.f)));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1.0f, 2.0f, 3.0f)");
}
INSTANTIATE_TEST_SUITE_P(
    HlslGeneratorImplTest_Import,
    HlslImportData_TripleParamTest,
    testing::Values(HlslImportData{"faceForward", "faceforward"},
                    HlslImportData{"fma", "fma"},
                    HlslImportData{"clamp", "clamp"},
                    HlslImportData{"smoothStep", "smoothstep"}));

TEST_F(HlslGeneratorImplTest_Import, DISABLED_HlslImportData_FMix) {
  FAIL();
}

using HlslImportData_TripleParam_Int_Test = TestParamHelper<HlslImportData>;
TEST_P(HlslImportData_TripleParam_Int_Test, IntScalar) {
  auto param = GetParam();

  ast::type::I32 i32;

  ast::ExpressionList params;
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 1)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 2)));
  params.push_back(create<ast::ScalarConstructorExpression>(
      create<ast::SintLiteral>(&i32, 3)));

  ast::CallExpression expr(create<ast::IdentifierExpression>(
                               mod.RegisterSymbol(param.name), param.name),
                           params);

  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string(param.hlsl_name) + "(1, 2, 3)");
}
INSTANTIATE_TEST_SUITE_P(HlslGeneratorImplTest_Import,
                         HlslImportData_TripleParam_Int_Test,
                         testing::Values(HlslImportData{"clamp", "clamp"}));

TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
  ast::type::F32 f32;
  ast::type::Matrix mat(&f32, 3, 3);

  auto* var =
      create<ast::Variable>(Source{},                        // source
                            "var",                           // name
                            ast::StorageClass::kFunction,    // storage_class
                            &mat,                            // type
                            false,                           // is_const
                            nullptr,                         // constructor
                            ast::VariableDecorationList{});  // decorations

  ast::ExpressionList params;
  params.push_back(
      create<ast::IdentifierExpression>(mod.RegisterSymbol("var"), "var"));

  ast::CallExpression expr(
      create<ast::IdentifierExpression>(mod.RegisterSymbol("determinant"),
                                        "determinant"),
      params);

  mod.AddGlobalVariable(var);

  // Register the global
  ASSERT_TRUE(td.Determine()) << td.error();
  ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
  ASSERT_TRUE(gen.EmitCall(pre, out, &expr)) << gen.error();
  EXPECT_EQ(result(), std::string("determinant(var)"));
}

}  // namespace
}  // namespace hlsl
}  // namespace writer
}  // namespace tint
