// 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 <cstring>

#include "src/writer/wgsl/test_helper.h"

namespace tint {
namespace writer {
namespace wgsl {
namespace {

// Makes an IEEE 754 binary32 floating point number with
// - 0 sign if sign is 0, 1 otherwise
// - 'exponent_bits' is placed in the exponent space.
//   So, the exponent bias must already be included.
float MakeFloat(int sign, int biased_exponent, int mantissa) {
  const uint32_t sign_bit = sign ? 0x80000000u : 0u;
  // The binary32 exponent is 8 bits, just below the sign.
  const uint32_t exponent_bits = (biased_exponent & 0xffu) << 23;
  // The mantissa is the bottom 23 bits.
  const uint32_t mantissa_bits = (mantissa & 0x7fffffu);

  uint32_t bits = sign_bit | exponent_bits | mantissa_bits;
  float result = 0.0f;
  static_assert(sizeof(result) == sizeof(bits),
                "expected float and uint32_t to be the same size");
  std::memcpy(&result, &bits, sizeof(bits));
  return result;
}

struct FloatData {
  float value;
  std::string expected;
};
inline std::ostream& operator<<(std::ostream& out, FloatData data) {
  out << "{" << data.value << "," << data.expected << "}";
  return out;
}

using WgslGenerator_FloatLiteralTest = TestParamHelper<FloatData>;

TEST_P(WgslGenerator_FloatLiteralTest, Emit) {
  auto* v = Expr(GetParam().value);

  SetResolveOnBuild(false);
  GeneratorImpl& gen = Build();

  std::stringstream out;
  ASSERT_TRUE(gen.EmitLiteral(out, v)) << gen.error();
  EXPECT_EQ(out.str(), GetParam().expected);
}

INSTANTIATE_TEST_SUITE_P(Zero,
                         WgslGenerator_FloatLiteralTest,
                         ::testing::ValuesIn(std::vector<FloatData>{
                             {0.0f, "0.0"},
                             {MakeFloat(0, 0, 0), "0.0"},
                             {MakeFloat(1, 0, 0), "-0.0"}}));

INSTANTIATE_TEST_SUITE_P(Normal,
                         WgslGenerator_FloatLiteralTest,
                         ::testing::ValuesIn(std::vector<FloatData>{
                             {1.0f, "1.0"},
                             {-1.0f, "-1.0"},
                             {101.375, "101.375"}}));

INSTANTIATE_TEST_SUITE_P(
    Subnormal,
    WgslGenerator_FloatLiteralTest,
    ::testing::ValuesIn(std::vector<FloatData>{
        {MakeFloat(0, 0, 1), "0x1p-149"},  // Smallest
        {MakeFloat(1, 0, 1), "-0x1p-149"},
        {MakeFloat(0, 0, 2), "0x1p-148"},
        {MakeFloat(1, 0, 2), "-0x1p-148"},
        {MakeFloat(0, 0, 0x7fffff), "0x1.fffffcp-127"},   // Largest
        {MakeFloat(1, 0, 0x7fffff), "-0x1.fffffcp-127"},  // Largest
        {MakeFloat(0, 0, 0xcafebe), "0x1.2bfaf8p-127"},   // Scattered bits
        {MakeFloat(1, 0, 0xcafebe), "-0x1.2bfaf8p-127"},  // Scattered bits
        {MakeFloat(0, 0, 0xaaaaa), "0x1.55554p-130"},     // Scattered bits
        {MakeFloat(1, 0, 0xaaaaa), "-0x1.55554p-130"},    // Scattered bits
    }));

INSTANTIATE_TEST_SUITE_P(Infinity,
                         WgslGenerator_FloatLiteralTest,
                         ::testing::ValuesIn(std::vector<FloatData>{
                             {MakeFloat(0, 255, 0), "0x1p+128"},
                             {MakeFloat(1, 255, 0), "-0x1p+128"}}));

INSTANTIATE_TEST_SUITE_P(
    // TODO(dneto): It's unclear how Infinity and NaN should be handled.
    // https://github.com/gpuweb/gpuweb/issues/1769
    // This test fails on Windows x86-64 because the machine sets the high
    // mantissa bit on NaNs.
    DISABLED_NaN,
    // In the NaN case, the top bit in the mantissa is often used to encode
    // whether the NaN is signalling or quiet, but no agreement between
    // different machine architectures on whether 1 means signalling or
    // if 1 means quiet.
    WgslGenerator_FloatLiteralTest,
    ::testing::ValuesIn(std::vector<FloatData>{
        // LSB only.  Smallest mantissa.
        {MakeFloat(0, 255, 1), "0x1.000002p+128"},  // Smallest mantissa
        {MakeFloat(1, 255, 1), "-0x1.000002p+128"},
        // MSB only.
        {MakeFloat(0, 255, 0x400000), "0x1.8p+128"},
        {MakeFloat(1, 255, 0x400000), "-0x1.8p+128"},
        // All 1s in the mantissa.
        {MakeFloat(0, 255, 0x7fffff), "0x1.fffffep+128"},
        {MakeFloat(1, 255, 0x7fffff), "-0x1.fffffep+128"},
        // Scattered bits, with 0 in top mantissa bit.
        {MakeFloat(0, 255, 0x20101f), "0x1.40203ep+128"},
        {MakeFloat(1, 255, 0x20101f), "-0x1.40203ep+128"},
        // Scattered bits, with 1 in top mantissa bit.
        {MakeFloat(0, 255, 0x40101f), "0x1.80203ep+128"},
        {MakeFloat(1, 255, 0x40101f), "-0x1.80203ep+128"}}));

}  // namespace
}  // namespace wgsl
}  // namespace writer
}  // namespace tint
