// © 2020 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.units;

import com.ibm.icu.util.MeasureUnit;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

import static java.math.MathContext.DECIMAL128;

public class UnitConverter {
    private BigDecimal conversionRate;
    private BigDecimal offset;

    /**
     * Constructor of `UnitConverter`.
     * NOTE:
     * - source and target must be under the same category
     * - e.g. meter to mile --> both of them are length units.
     *
     * @param source          represents the source unit.
     * @param target          represents the target unit.
     * @param conversionRates contains all the needed conversion rates.
     */
    public UnitConverter(MeasureUnitImpl source, MeasureUnitImpl target, ConversionRates conversionRates) {
        Convertibility convertibility = extractConvertibility(source, target, conversionRates);
        assert (convertibility == Convertibility.CONVERTIBLE || convertibility == Convertibility.RECIPROCAL);

        Factor sourceToBase = conversionRates.getFactorToBase(source);
        Factor targetToBase = conversionRates.getFactorToBase(target);

        if (convertibility == Convertibility.CONVERTIBLE) {
            this.conversionRate = sourceToBase.divide(targetToBase).getConversionRate();
        } else {
            this.conversionRate = sourceToBase.multiply(targetToBase).getConversionRate();
        }

        // calculate the offset
        this.offset = conversionRates.getOffset(source, target, sourceToBase, targetToBase, convertibility);
    }

    static public Convertibility extractConvertibility(MeasureUnitImpl source, MeasureUnitImpl target, ConversionRates conversionRates) {
        ArrayList<SingleUnitImpl> sourceSingleUnits = conversionRates.extractBaseUnits(source);
        ArrayList<SingleUnitImpl> targetSingleUnits = conversionRates.extractBaseUnits(target);

        HashMap<String, Integer> dimensionMap = new HashMap<>();

        insertInMap(dimensionMap, sourceSingleUnits, 1);
        insertInMap(dimensionMap, targetSingleUnits, -1);

        if (areDimensionsZeroes(dimensionMap)) return Convertibility.CONVERTIBLE;

        insertInMap(dimensionMap, targetSingleUnits, 2);
        if (areDimensionsZeroes(dimensionMap)) return Convertibility.RECIPROCAL;

        return Convertibility.UNCONVERTIBLE;
    }

    /**
     * Helpers
     */
    private static void insertInMap(HashMap<String, Integer> dimensionMap, ArrayList<SingleUnitImpl> singleUnits, int multiplier) {
        for (SingleUnitImpl singleUnit :
                singleUnits) {
            if (dimensionMap.containsKey(singleUnit.getSimpleUnit())) {
                dimensionMap.put(singleUnit.getSimpleUnit(), dimensionMap.get(singleUnit.getSimpleUnit()) + singleUnit.getDimensionality() * multiplier);
            } else {
                dimensionMap.put(singleUnit.getSimpleUnit(), singleUnit.getDimensionality() * multiplier);
            }
        }
    }

    private static boolean areDimensionsZeroes(HashMap<String, Integer> dimensionMap) {
        for (Integer value :
                dimensionMap.values()) {
            if (!value.equals(0)) return false;
        }

        return true;
    }

    public BigDecimal convert(BigDecimal inputValue) {
        return inputValue.multiply(this.conversionRate).add(offset);
    }

    public BigDecimal convertInverse(BigDecimal inputValue) {
        return inputValue.subtract(offset).divide(this.conversionRate, DECIMAL128);
    }

    public enum Convertibility {
        CONVERTIBLE,
        RECIPROCAL,
        UNCONVERTIBLE,
    }

    // TODO: improve documentation and Constant implementation

    /**
     * Responsible for all the Factor operation
     * NOTE:
     * This class is immutable
     */
    static class Factor {
        private BigDecimal factorNum;
        private BigDecimal factorDen;
        /* FACTOR CONSTANTS */
        private int
                CONSTANT_FT2M = 0,    // ft2m stands for foot to meter.
                CONSTANT_PI = 0,      // PI
                CONSTANT_GRAVITY = 0, // Gravity
                CONSTANT_G = 0,
                CONSTANT_GAL_IMP2M3 = 0, // Gallon imp to m3
                CONSTANT_LB2KG = 0;      // Pound to Kilogram


        /**
         * Creates Empty Factor
         */
        public Factor() {
            this.factorNum = BigDecimal.valueOf(1);
            this.factorDen = BigDecimal.valueOf(1);
        }

        public static Factor processFactor(String factor) {
            assert (!factor.isEmpty());

            // Remove all spaces in the factor
            factor.replaceAll("\\s+", "");

            String[] fractions = factor.split("/");
            assert (fractions.length == 1 || fractions.length == 2);

            if (fractions.length == 1) {
                return processFactorWithoutDivision(fractions[0]);
            }

            Factor num = processFactorWithoutDivision(fractions[0]);
            Factor den = processFactorWithoutDivision(fractions[1]);
            return num.divide(den);
        }

        private static Factor processFactorWithoutDivision(String factorWithoutDivision) {
            Factor result = new Factor();
            for (String poweredEntity :
                    factorWithoutDivision.split(Pattern.quote("*"))) {
                result.addPoweredEntity(poweredEntity);
            }

            return result;
        }

        /**
         * Clone this <code>Factor</code>.
         */
        protected Factor clone() {
            Factor result = new Factor();
            result.factorNum = this.factorNum;
            result.factorDen = this.factorDen;

            result.CONSTANT_FT2M = this.CONSTANT_FT2M;
            result.CONSTANT_PI = this.CONSTANT_PI;
            result.CONSTANT_GRAVITY = this.CONSTANT_GRAVITY;
            result.CONSTANT_G = this.CONSTANT_G;
            result.CONSTANT_GAL_IMP2M3 = this.CONSTANT_GAL_IMP2M3;
            result.CONSTANT_LB2KG = this.CONSTANT_LB2KG;

            return result;
        }

        /**
         * Returns a single `BigDecimal` that represent the conversion rate after substituting all the constants.
         *
         * @return
         */
        public BigDecimal getConversionRate() {
            Factor resultCollector = this.clone();

            resultCollector.substitute(new BigDecimal("0.3048"), this.CONSTANT_FT2M);
            resultCollector.substitute(new BigDecimal("411557987.0").divide(new BigDecimal("131002976.0"), DECIMAL128), this.CONSTANT_PI);
            resultCollector.substitute(new BigDecimal("9.80665"), this.CONSTANT_GRAVITY);
            resultCollector.substitute(new BigDecimal("6.67408E-11"), this.CONSTANT_G);
            resultCollector.substitute(new BigDecimal("0.00454609"), this.CONSTANT_GAL_IMP2M3);
            resultCollector.substitute(new BigDecimal("0.45359237"), this.CONSTANT_LB2KG);

            return resultCollector.factorNum.divide(resultCollector.factorDen, DECIMAL128);
        }

        private void substitute(BigDecimal value, int power) {
            if (power == 0) return;

            BigDecimal absPoweredValue = value.pow(Math.abs(power), DECIMAL128);
            if (power > 0) {
                this.factorNum = this.factorNum.multiply(absPoweredValue);
            } else {
                this.factorDen = this.factorDen.multiply(absPoweredValue);
            }
        }

        public Factor applySiPrefix(MeasureUnit.SIPrefix siPrefix) {
            Factor result = this.clone();
            if (siPrefix == MeasureUnit.SIPrefix.ONE) {
                return result;
            }

            BigDecimal siApplied = BigDecimal.valueOf(Math.pow(10.0, Math.abs(siPrefix.getPower())));

            if (siPrefix.getPower() < 0) {
                result.factorDen = this.factorDen.multiply(siApplied);
                return result;
            }

            result.factorNum = this.factorNum.multiply(siApplied);
            return result;
        }

        public Factor power(int power) {
            Factor result = new Factor();
            if (power == 0) return result;
            if (power > 0) {
                result.factorNum = this.factorNum.pow(power);
                result.factorDen = this.factorDen.pow(power);
            } else {
                result.factorNum = this.factorDen.pow(power * -1);
                result.factorDen = this.factorNum.pow(power * -1);
            }

            result.CONSTANT_FT2M = this.CONSTANT_FT2M * power;
            result.CONSTANT_PI = this.CONSTANT_PI * power;
            result.CONSTANT_GRAVITY = this.CONSTANT_GRAVITY * power;
            result.CONSTANT_G = this.CONSTANT_G * power;
            result.CONSTANT_GAL_IMP2M3 = this.CONSTANT_GAL_IMP2M3 * power;
            result.CONSTANT_LB2KG = this.CONSTANT_LB2KG * power;

            return result;
        }

        public Factor divide(Factor other) {
            Factor result = new Factor();
            result.factorNum = this.factorNum.multiply(other.factorDen);
            result.factorDen = this.factorDen.multiply(other.factorNum);

            result.CONSTANT_FT2M = this.CONSTANT_FT2M - other.CONSTANT_FT2M;
            result.CONSTANT_PI = this.CONSTANT_PI - other.CONSTANT_PI;
            result.CONSTANT_GRAVITY = this.CONSTANT_GRAVITY - other.CONSTANT_GRAVITY;
            result.CONSTANT_G = this.CONSTANT_G - other.CONSTANT_G;
            result.CONSTANT_GAL_IMP2M3 = this.CONSTANT_GAL_IMP2M3 - other.CONSTANT_GAL_IMP2M3;
            result.CONSTANT_LB2KG = this.CONSTANT_LB2KG - other.CONSTANT_LB2KG;

            return result;
        }

        public Factor multiply(Factor other) {
            Factor result = new Factor();
            result.factorNum = this.factorNum.multiply(other.factorNum);
            result.factorDen = this.factorDen.multiply(other.factorDen);

            result.CONSTANT_FT2M = this.CONSTANT_FT2M + other.CONSTANT_FT2M;
            result.CONSTANT_PI = this.CONSTANT_PI + other.CONSTANT_PI;
            result.CONSTANT_GRAVITY = this.CONSTANT_GRAVITY + other.CONSTANT_GRAVITY;
            result.CONSTANT_G = this.CONSTANT_G + other.CONSTANT_G;
            result.CONSTANT_GAL_IMP2M3 = this.CONSTANT_GAL_IMP2M3 + other.CONSTANT_GAL_IMP2M3;
            result.CONSTANT_LB2KG = this.CONSTANT_LB2KG + other.CONSTANT_LB2KG;

            return result;
        }

        /**
         * Adds Entity with power or not. For example, `12 ^ 3` or `12`.
         *
         * @param poweredEntity
         */
        private void addPoweredEntity(String poweredEntity) {
            String[] entities = poweredEntity.split(Pattern.quote("^"));
            assert (entities.length == 1 || entities.length == 2);

            int power = entities.length == 2 ? Integer.parseInt(entities[1]) : 1;
            this.addEntity(entities[0], power);
        }

        private void addEntity(String entity, int power) {
            if ("ft_to_m".equals(entity)) {
                this.CONSTANT_FT2M += power;
            } else if ("ft2_to_m2".equals(entity)) {
                this.CONSTANT_FT2M += 2 * power;
            } else if ("ft3_to_m3".equals(entity)) {
                this.CONSTANT_FT2M += 3 * power;
            } else if ("in3_to_m3".equals(entity)) {
                this.CONSTANT_FT2M += 3 * power;
                this.factorDen = this.factorDen.multiply(BigDecimal.valueOf(Math.pow(12, 3)));
            } else if ("gal_to_m3".equals(entity)) {
                this.factorNum = this.factorNum.multiply(BigDecimal.valueOf(231));
                this.CONSTANT_FT2M += 3 * power;
                this.factorDen = this.factorDen.multiply(BigDecimal.valueOf(12 * 12 * 12));
            } else if ("gal_imp_to_m3".equals(entity)) {
                this.CONSTANT_GAL_IMP2M3 += power;
            } else if ("G".equals(entity)) {
                this.CONSTANT_G += power;
            } else if ("gravity".equals(entity)) {
                this.CONSTANT_GRAVITY += power;
            } else if ("lb_to_kg".equals(entity)) {
                this.CONSTANT_LB2KG += power;
            } else if ("PI".equals(entity)) {
                this.CONSTANT_PI += power;
            } else {
                BigDecimal decimalEntity = new BigDecimal(entity).pow(power, DECIMAL128);
                this.factorNum = this.factorNum.multiply(decimalEntity);
            }
        }
    }

    @Override
    public String toString() {
        return "UnitConverter [conversionRate=" + conversionRate + ", offset=" + offset + "]";
    }
}
