// 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/float_to_string.h"

#include <cmath>
#include <cstring>
#include <iomanip>
#include <limits>
#include <sstream>

#include "src/debug.h"

namespace tint {
namespace writer {

std::string FloatToString(float f) {
  std::stringstream ss;
  ss.flags(ss.flags() | std::ios_base::showpoint | std::ios_base::fixed);
  ss.precision(std::numeric_limits<float>::max_digits10);
  ss << f;
  auto str = ss.str();
  while (str.length() >= 2 && str[str.size() - 1] == '0' &&
         str[str.size() - 2] != '.') {
    str.pop_back();
  }
  return str;
}

std::string FloatToBitPreservingString(float f) {
  // For the NaN case, avoid handling the number as a floating point value.
  // Some machines will modify the top bit in the mantissa of a NaN.

  std::stringstream ss;

  uint32_t float_bits = 0u;
  std::memcpy(&float_bits, &f, sizeof(float_bits));

  // Handle the sign.
  const uint32_t kSignMask = 1u << 31;
  if (float_bits & kSignMask) {
    // If `f` is -0.0 print -0.0.
    ss << '-';
    // Strip sign bit.
    float_bits = float_bits & (~kSignMask);
  }

  switch (std::fpclassify(f)) {
    case FP_ZERO:
    case FP_NORMAL:
      std::memcpy(&f, &float_bits, sizeof(float_bits));
      ss << FloatToString(f);
      break;

    default: {
      // Infinity, NaN, and Subnormal
      // TODO(dneto): It's unclear how Infinity and NaN should be handled.
      // See https://github.com/gpuweb/gpuweb/issues/1769

      // std::hexfloat prints 'nan' and 'inf' instead of an
      // explicit representation like we want. Split it out
      // manually.
      const int kExponentBias = 127;
      const int kExponentMask = 0x7f800000;
      const int kMantissaMask = 0x007fffff;
      const int kMantissaBits = 23;

      int mantissaNibbles = (kMantissaBits + 3) / 4;

      const int biased_exponent =
          static_cast<int>((float_bits & kExponentMask) >> kMantissaBits);
      int exponent = biased_exponent - kExponentBias;
      uint32_t mantissa = float_bits & kMantissaMask;

      ss << "0x";

      if (exponent == 128) {
        if (mantissa == 0) {
          //  Infinity case.
          ss << "1p+128";
        } else {
          //  NaN case.
          //  Emit the mantissa bits as if they are left-justified after the
          //  binary point.  This is what SPIRV-Tools hex float emitter does,
          //  and it's a justifiable choice independent of the bit width
          //  of the mantissa.
          mantissa <<= (4 - (kMantissaBits % 4));
          // Remove trailing zeroes, for tidyness.
          while (0 == (0xf & mantissa)) {
            mantissa >>= 4;
            mantissaNibbles--;
          }
          ss << "1." << std::hex << std::setfill('0')
             << std::setw(mantissaNibbles) << mantissa << "p+128";
        }
      } else {
        // Subnormal, and not zero.
        TINT_ASSERT(mantissa != 0);
        const int kTopBit = (1 << kMantissaBits);

        // Shift left until we get 1.x
        while (0 == (kTopBit & mantissa)) {
          mantissa <<= 1;
          exponent--;
        }
        // Emit the leading 1, and remove it from the mantissa.
        ss << "1";
        mantissa = mantissa ^ kTopBit;
        mantissa <<= 1;
        exponent++;

        // Emit the fractional part.
        if (mantissa) {
          // Remove trailing zeroes, for tidyness
          while (0 == (0xf & mantissa)) {
            mantissa >>= 4;
            mantissaNibbles--;
          }
          ss << "." << std::hex << std::setfill('0')
             << std::setw(mantissaNibbles) << mantissa;
        }
        // Emit the exponent
        ss << "p" << std::showpos << std::dec << exponent;
      }
    }
  }
  return ss.str();
}

}  // namespace writer
}  // namespace tint
