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