// 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/ast/override_decoration.h"
#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.EmitScalarConstructor(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
