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

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

#include "src/tint/debug.h"

namespace tint::writer {

std::string FloatToString(float f) {
    // Try printing the float in fixed point, with a smallish limit on the
    // precision
    std::stringstream fixed;
    fixed.flags(fixed.flags() | std::ios_base::showpoint | std::ios_base::fixed);
    fixed.imbue(std::locale::classic());
    fixed.precision(9);
    fixed << f;
    std::string str = fixed.str();

    // If this string can be parsed without loss of information, use it.
    // (Use double here to dodge a bug in older libc++ versions which
    // would incorrectly read back FLT_MAX as INF.)
    double roundtripped;
    fixed >> roundtripped;

    auto float_equal_no_warning = std::equal_to<float>();
    if (float_equal_no_warning(f, static_cast<float>(roundtripped))) {
        while (str.length() >= 2 && str[str.size() - 1] == '0' && str[str.size() - 2] != '.') {
            str.pop_back();
        }

        return str;
    }

    // Resort to scientific, with the minimum precision needed to preserve the
    // whole float
    std::stringstream sci;
    sci.imbue(std::locale::classic());
    sci.precision(std::numeric_limits<float>::max_digits10);
    sci << f;
    return sci.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(Writer, 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 tint::writer
