/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */

package org.apache.harmony.luni.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * Parses hex string to a single or double precision floating point number.
 */
final class HexStringParser {

    private static final int DOUBLE_EXPONENT_WIDTH = 11;

    private static final int DOUBLE_MANTISSA_WIDTH = 52;

    private static final int FLOAT_EXPONENT_WIDTH = 8;

    private static final int FLOAT_MANTISSA_WIDTH = 23;

    private static final int HEX_RADIX = 16;

    private static final int MAX_SIGNIFICANT_LENGTH = 15;

    private static final String HEX_SIGNIFICANT = "0[xX](\\p{XDigit}+\\.?|\\p{XDigit}*\\.\\p{XDigit}+)";

    private static final String BINARY_EXPONENT = "[pP]([+-]?\\d+)";

    private static final String FLOAT_TYPE_SUFFIX = "[fFdD]?";

    private static final String HEX_PATTERN = "[\\x00-\\x20]*([+-]?)" + HEX_SIGNIFICANT
            + BINARY_EXPONENT + FLOAT_TYPE_SUFFIX + "[\\x00-\\x20]*";

    private static final Pattern PATTERN = Pattern.compile(HEX_PATTERN);

    private final int EXPONENT_WIDTH;

    private final int MANTISSA_WIDTH;

    private final long EXPONENT_BASE;

    private final long MAX_EXPONENT;

    private final long MIN_EXPONENT;

    private final long MANTISSA_MASK;

    private long sign;

    private long exponent;

    private long mantissa;

    private String abandonedNumber="";

    public HexStringParser(int exponent_width, int mantissa_width) {
        this.EXPONENT_WIDTH = exponent_width;
        this.MANTISSA_WIDTH = mantissa_width;

        this.EXPONENT_BASE = ~(-1L << (exponent_width - 1));
        this.MAX_EXPONENT = ~(-1L << exponent_width);
        this.MIN_EXPONENT = -(MANTISSA_WIDTH + 1);
        this.MANTISSA_MASK = ~(-1L << mantissa_width);
    }

    /*
     * Parses the hex string to a double number.
     */
    public static double parseDouble(String hexString) {
        HexStringParser parser = new HexStringParser(DOUBLE_EXPONENT_WIDTH,
                DOUBLE_MANTISSA_WIDTH);
        long result = parser.parse(hexString);
        return Double.longBitsToDouble(result);
    }

    /*
     * Parses the hex string to a float number.
     */
    public static float parseFloat(String hexString) {
        HexStringParser parser = new HexStringParser(FLOAT_EXPONENT_WIDTH,
                FLOAT_MANTISSA_WIDTH);
        int result = (int) parser.parse(hexString);
        return Float.intBitsToFloat(result);
    }

    private long parse(String hexString) {
        String[] hexSegments = getSegmentsFromHexString(hexString);
        String signStr = hexSegments[0];
        String significantStr = hexSegments[1];
        String exponentStr = hexSegments[2];

        parseHexSign(signStr);
        parseExponent(exponentStr);
        parseMantissa(significantStr);

        sign <<= (MANTISSA_WIDTH + EXPONENT_WIDTH);
        exponent <<= MANTISSA_WIDTH;
        return sign | exponent | mantissa;
    }

    /*
     * Analyzes the hex string and extracts the sign and digit segments.
     */
    private static String[] getSegmentsFromHexString(String hexString) {
        Matcher matcher = PATTERN.matcher(hexString);
        if (!matcher.matches()) {
            throw new NumberFormatException();
        }

        String[] hexSegments = new String[3];
        hexSegments[0] = matcher.group(1);
        hexSegments[1] = matcher.group(2);
        hexSegments[2] = matcher.group(3);

        return hexSegments;
    }

    /*
     * Parses the sign field.
     */
    private void parseHexSign(String signStr) {
        this.sign = signStr.equals("-") ? 1 : 0;
    }

    /*
     * Parses the exponent field.
     */
    private void parseExponent(String exponentStr) {
        char leadingChar = exponentStr.charAt(0);
        int expSign = (leadingChar == '-' ? -1 : 1);
        if (!Character.isDigit(leadingChar)) {
            exponentStr = exponentStr.substring(1);
        }

        try {
            exponent = expSign * Long.parseLong(exponentStr);
            checkedAddExponent(EXPONENT_BASE);
        } catch (NumberFormatException e) {
            exponent = expSign * Long.MAX_VALUE;
        }
    }

    /*
     * Parses the mantissa field.
     */
    private void parseMantissa(String significantStr) {
        String[] strings = significantStr.split("\\.");
        String strIntegerPart = strings[0];
        String strDecimalPart = strings.length > 1 ? strings[1] : "";

        String significand = getNormalizedSignificand(strIntegerPart,strDecimalPart);
        if (significand.equals("0")) {
            setZero();
            return;
        }

        int offset = getOffset(strIntegerPart, strDecimalPart);
        checkedAddExponent(offset);

        if (exponent >= MAX_EXPONENT) {
            setInfinite();
            return;
        }

        if (exponent <= MIN_EXPONENT) {
            setZero();
            return;
        }

        if (significand.length() > MAX_SIGNIFICANT_LENGTH) {
            abandonedNumber = significand.substring(MAX_SIGNIFICANT_LENGTH);
            significand = significand.substring(0, MAX_SIGNIFICANT_LENGTH);
        }

        mantissa = Long.parseLong(significand, HEX_RADIX);

        if (exponent >= 1) {
            processNormalNumber();
        } else{
            processSubNormalNumber();
        }

    }

    private void setInfinite() {
        exponent = MAX_EXPONENT;
        mantissa = 0;
    }

    private void setZero() {
        exponent = 0;
        mantissa = 0;
    }

    /*
     * Sets the exponent variable to Long.MAX_VALUE or -Long.MAX_VALUE if
     * overflow or underflow happens.
     */
    private void checkedAddExponent(long offset) {
        long result = exponent + offset;
        int expSign = Long.signum(exponent);
        if (expSign * Long.signum(offset) > 0 && expSign * Long.signum(result) < 0) {
            exponent = expSign * Long.MAX_VALUE;
        } else {
            exponent = result;
        }
    }

    private void processNormalNumber(){
        int desiredWidth = MANTISSA_WIDTH + 2;
        fitMantissaInDesiredWidth(desiredWidth);
        round();
        mantissa = mantissa & MANTISSA_MASK;
    }

    private void processSubNormalNumber(){
        int desiredWidth = MANTISSA_WIDTH + 1;
        desiredWidth += (int)exponent;//lends bit from mantissa to exponent
        exponent = 0;
        fitMantissaInDesiredWidth(desiredWidth);
        round();
        mantissa = mantissa & MANTISSA_MASK;
    }

    /*
     * Adjusts the mantissa to desired width for further analysis.
     */
    private void fitMantissaInDesiredWidth(int desiredWidth){
        int bitLength = countBitsLength(mantissa);
        if (bitLength > desiredWidth) {
            discardTrailingBits(bitLength - desiredWidth);
        } else {
            mantissa <<= (desiredWidth - bitLength);
        }
    }

    /*
     * Stores the discarded bits to abandonedNumber.
     */
    private void discardTrailingBits(long num) {
        long mask = ~(-1L << num);
        abandonedNumber += (mantissa & mask);
        mantissa >>= num;
    }

    /*
     * The value is rounded up or down to the nearest infinitely precise result.
     * If the value is exactly halfway between two infinitely precise results,
     * then it should be rounded up to the nearest infinitely precise even.
     */
    private void round() {
        String result = abandonedNumber.replaceAll("0+", "");
        boolean moreThanZero = (result.length() > 0 ? true : false);

        int lastDiscardedBit = (int) (mantissa & 1L);
        mantissa >>= 1;
        int tailBitInMantissa = (int) (mantissa & 1L);

        if (lastDiscardedBit == 1 && (moreThanZero || tailBitInMantissa == 1)) {
            int oldLength = countBitsLength(mantissa);
            mantissa += 1L;
            int newLength = countBitsLength(mantissa);

            //Rounds up to exponent when whole bits of mantissa are one-bits.
            if (oldLength >= MANTISSA_WIDTH && newLength > oldLength) {
                checkedAddExponent(1);
            }
        }
    }

    /*
     * Returns the normalized significand after removing the leading zeros.
     */
    private String getNormalizedSignificand(String strIntegerPart, String strDecimalPart) {
        String significand = strIntegerPart + strDecimalPart;
        significand = significand.replaceFirst("^0+", "");
        if (significand.length() == 0) {
            significand = "0";
        }
        return significand;
    }

    /*
     * Calculates the offset between the normalized number and unnormalized
     * number. In a normalized representation, significand is represented by the
     * characters "0x1." followed by a lowercase hexadecimal representation of
     * the rest of the significand as a fraction.
     */
    private int getOffset(String strIntegerPart, String strDecimalPart) {
        strIntegerPart = strIntegerPart.replaceFirst("^0+", "");

        //If the Integer part is a nonzero number.
        if (strIntegerPart.length() != 0) {
            String leadingNumber = strIntegerPart.substring(0, 1);
            return (strIntegerPart.length() - 1) * 4 + countBitsLength(Long.parseLong(leadingNumber,HEX_RADIX)) - 1;
        }

        //If the Integer part is a zero number.
        int i;
        for (i = 0; i < strDecimalPart.length() && strDecimalPart.charAt(i) == '0'; i++);
        if (i == strDecimalPart.length()) {
            return 0;
        }
        String leadingNumber=strDecimalPart.substring(i,i + 1);
        return (-i - 1) * 4 + countBitsLength(Long.parseLong(leadingNumber, HEX_RADIX)) - 1;
    }

    private int countBitsLength(long value) {
        int leadingZeros = Long.numberOfLeadingZeros(value);
        return Long.SIZE - leadingZeros;
    }
}
