##############################################################################
#                                                                            #
#  Copyright 2006-2019 WebPKI.org (http://webpki.org).                       #
#                                                                            #
#  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                                   #
#                                                                            #
#      https://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.                                            #
#                                                                            #
##############################################################################


##################################################################
# Convert a Python double/float into an ES6/V8 compatible string #
##################################################################
def convert2Es6Format(value):
    # Convert double/float to str using the native Python formatter
    fvalue = float(value)
    #
    # Zero is a special case.  The following line takes "-0" case as well
    #
    if fvalue == 0:
        return "0"
    #
    # The rest of the algorithm works on the textual representation only
    #
    pyDouble = str(fvalue)
    #
    # The following line catches the "inf" and "nan" values returned by str(fvalue)
    #
    if pyDouble.find("n") >= 0:
        raise ValueError("Invalid JSON number: " + pyDouble)
    #
    # Save sign separately, it doesn't have any role in the algorithm
    #
    pySign = ""
    if pyDouble.find("-") == 0:
        pySign = "-"
        pyDouble = pyDouble[1:]
    #
    # Now we should only have valid non-zero values
    #
    pyExpStr = ""
    pyExpVal = 0
    q = pyDouble.find("e")
    if q > 0:
        #
        # Grab the exponent and remove it from the number
        #
        pyExpStr = pyDouble[q:]
        if pyExpStr[2:3] == "0":
            #
            # Supress leading zero on exponents
            #
            pyExpStr = pyExpStr[:2] + pyExpStr[3:]
        pyDouble = pyDouble[0:q]
        pyExpVal = int(pyExpStr[1:])
    #
    # Split number in pyFirst + pyDot + pyLast
    #
    pyFirst = pyDouble
    pyDot = ""
    pyLast = ""
    q = pyDouble.find(".")
    if q > 0:
        pyDot = "."
        pyFirst = pyDouble[:q]
        pyLast = pyDouble[q + 1 :]
    #
    # Now the string is split into: pySign + pyFirst + pyDot + pyLast + pyExpStr
    #
    if pyLast == "0":
        #
        # Always remove trailing .0
        #
        pyDot = ""
        pyLast = ""
    if pyExpVal > 0 and pyExpVal < 21:
        #
        # Integers are shown as is with up to 21 digits
        #
        pyFirst += pyLast
        pyLast = ""
        pyDot = ""
        pyExpStr = ""
        q = pyExpVal - len(pyFirst)
        while q >= 0:
            q -= 1
            pyFirst += "0"
    elif pyExpVal < 0 and pyExpVal > -7:
        #
        # Small numbers are shown as 0.etc with e-6 as lower limit
        #
        pyLast = pyFirst + pyLast
        pyFirst = "0"
        pyDot = "."
        pyExpStr = ""
        q = pyExpVal
        while q < -1:
            q += 1
            pyLast = "0" + pyLast
    #
    # The resulting sub-strings are concatenated
    #
    return pySign + pyFirst + pyDot + pyLast + pyExpStr
