// 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/writer/msl/test_helper.h"

namespace tint {
namespace writer {
namespace msl {
namespace {

struct BinaryData {
  const char* result;
  ast::BinaryOp op;
};
inline std::ostream& operator<<(std::ostream& out, BinaryData data) {
  out << data.op;
  return out;
}
using MslBinaryTest = TestParamHelper<BinaryData>;
TEST_P(MslBinaryTest, Emit) {
  auto params = GetParam();

  auto type = [&] {
    return ((params.op == ast::BinaryOp::kLogicalAnd) ||
            (params.op == ast::BinaryOp::kLogicalOr))
               ? static_cast<ast::Type*>(ty.bool_())
               : static_cast<ast::Type*>(ty.u32());
  };

  auto* left = Var("left", type());
  auto* right = Var("right", type());

  auto* expr =
      create<ast::BinaryExpression>(params.op, Expr(left), Expr(right));
  WrapInFunction(left, right, expr);

  GeneratorImpl& gen = Build();

  std::stringstream out;
  ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
  EXPECT_EQ(out.str(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
    MslGeneratorImplTest,
    MslBinaryTest,
    testing::Values(
        BinaryData{"(left & right)", ast::BinaryOp::kAnd},
        BinaryData{"(left | right)", ast::BinaryOp::kOr},
        BinaryData{"(left ^ right)", ast::BinaryOp::kXor},
        BinaryData{"(left && right)", ast::BinaryOp::kLogicalAnd},
        BinaryData{"(left || right)", ast::BinaryOp::kLogicalOr},
        BinaryData{"(left == right)", ast::BinaryOp::kEqual},
        BinaryData{"(left != right)", ast::BinaryOp::kNotEqual},
        BinaryData{"(left < right)", ast::BinaryOp::kLessThan},
        BinaryData{"(left > right)", ast::BinaryOp::kGreaterThan},
        BinaryData{"(left <= right)", ast::BinaryOp::kLessThanEqual},
        BinaryData{"(left >= right)", ast::BinaryOp::kGreaterThanEqual},
        BinaryData{"(left << right)", ast::BinaryOp::kShiftLeft},
        BinaryData{"(left >> right)", ast::BinaryOp::kShiftRight},
        BinaryData{"(left + right)", ast::BinaryOp::kAdd},
        BinaryData{"(left - right)", ast::BinaryOp::kSubtract},
        BinaryData{"(left * right)", ast::BinaryOp::kMultiply},
        BinaryData{"(left / right)", ast::BinaryOp::kDivide},
        BinaryData{"(left % right)", ast::BinaryOp::kModulo}));

TEST_F(MslBinaryTest, ModF32) {
  auto* left = Var("left", ty.f32());
  auto* right = Var("right", ty.f32());
  auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr(left),
                                             Expr(right));
  WrapInFunction(left, right, expr);

  GeneratorImpl& gen = Build();

  std::stringstream out;
  ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
  EXPECT_EQ(out.str(), "fmod(left, right)");
}

TEST_F(MslBinaryTest, ModVec3F32) {
  auto* left = Var("left", ty.vec3<f32>());
  auto* right = Var("right", ty.vec3<f32>());
  auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr(left),
                                             Expr(right));
  WrapInFunction(left, right, expr);

  GeneratorImpl& gen = Build();

  std::stringstream out;
  ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
  EXPECT_EQ(out.str(), "fmod(left, right)");
}

}  // namespace
}  // namespace msl
}  // namespace writer
}  // namespace tint
