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

import java.math.BigDecimal;
import java.math.MathContext;

import com.ibm.icu.impl.number.AffixPatternProvider;
import com.ibm.icu.impl.number.CustomSymbolCurrency;
import com.ibm.icu.impl.number.DecimalFormatProperties;
import com.ibm.icu.impl.number.Grouper;
import com.ibm.icu.impl.number.MacroProps;
import com.ibm.icu.impl.number.Padder;
import com.ibm.icu.impl.number.PatternStringParser;
import com.ibm.icu.impl.number.PatternStringUtils;
import com.ibm.icu.impl.number.PropertiesAffixPatternProvider;
import com.ibm.icu.impl.number.RoundingUtils;
import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay;
import com.ibm.icu.number.NumberFormatter.SignDisplay;
import com.ibm.icu.number.Precision.FractionRounderImpl;
import com.ibm.icu.number.Precision.IncrementRounderImpl;
import com.ibm.icu.number.Precision.SignificantRounderImpl;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Currency.CurrencyUsage;
import com.ibm.icu.util.ULocale;

/**
 * <p>
 * This class, as well as NumberFormatterImpl, could go into the impl package, but they depend on too
 * many package-private members of the public APIs.
 */
final class NumberPropertyMapper {

    /** Convenience method to create a NumberFormatter directly from Properties. */
    public static UnlocalizedNumberFormatter create(
            DecimalFormatProperties properties,
            DecimalFormatSymbols symbols) {
        MacroProps macros = oldToNew(properties, symbols, null);
        return NumberFormatter.with().macros(macros);
    }

    /** Convenience method to create a NumberFormatter directly from Properties. */
    public static UnlocalizedNumberFormatter create(
            DecimalFormatProperties properties,
            DecimalFormatSymbols symbols,
            DecimalFormatProperties exportedProperties) {
        MacroProps macros = oldToNew(properties, symbols, exportedProperties);
        return NumberFormatter.with().macros(macros);
    }

    /**
     * Convenience method to create a NumberFormatter directly from a pattern string. Something like this
     * could become public API if there is demand.
     *
     * NOTE: This appears to be dead code.
     */
    public static UnlocalizedNumberFormatter create(String pattern, DecimalFormatSymbols symbols) {
        DecimalFormatProperties properties = PatternStringParser.parseToProperties(pattern);
        return create(properties, symbols);
    }

    /**
     * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
     * object. In other words, maps Properties to MacroProps. This function is used by the
     * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
     *
     * @param properties
     *            The property bag to be mapped.
     * @param symbols
     *            The symbols associated with the property bag.
     * @param exportedProperties
     *            A property bag in which to store validated properties. Used by some DecimalFormat
     *            getters.
     * @return A new MacroProps containing all of the information in the Properties.
     */
    public static MacroProps oldToNew(
            DecimalFormatProperties properties,
            DecimalFormatSymbols symbols,
            DecimalFormatProperties exportedProperties) {
        MacroProps macros = new MacroProps();
        ULocale locale = symbols.getULocale();

        /////////////
        // SYMBOLS //
        /////////////

        macros.symbols = symbols;

        //////////////////
        // PLURAL RULES //
        //////////////////

        PluralRules rules = properties.getPluralRules();
        if (rules == null && properties.getCurrencyPluralInfo() != null) {
            rules = properties.getCurrencyPluralInfo().getPluralRules();
        }
        macros.rules = rules;

        /////////////
        // AFFIXES //
        /////////////

        AffixPatternProvider affixProvider = PropertiesAffixPatternProvider.forProperties(properties);
        macros.affixProvider = affixProvider;

        ///////////
        // UNITS //
        ///////////

        boolean useCurrency = ((properties.getCurrency() != null)
                || properties.getCurrencyPluralInfo() != null
                || properties.getCurrencyUsage() != null
                || affixProvider.hasCurrencySign());
        Currency currency = CustomSymbolCurrency.resolve(properties.getCurrency(), locale, symbols);
        CurrencyUsage currencyUsage = properties.getCurrencyUsage();
        boolean explicitCurrencyUsage = currencyUsage != null;
        if (!explicitCurrencyUsage) {
            currencyUsage = CurrencyUsage.STANDARD;
        }
        if (useCurrency) {
            macros.unit = currency;
        }

        ///////////////////////
        // ROUNDING STRATEGY //
        ///////////////////////

        int maxInt = properties.getMaximumIntegerDigits();
        int minInt = properties.getMinimumIntegerDigits();
        int maxFrac = properties.getMaximumFractionDigits();
        int minFrac = properties.getMinimumFractionDigits();
        int minSig = properties.getMinimumSignificantDigits();
        int maxSig = properties.getMaximumSignificantDigits();
        BigDecimal roundingIncrement = properties.getRoundingIncrement();
        MathContext mathContext = RoundingUtils.getMathContextOrUnlimited(properties);
        boolean explicitMinMaxFrac = minFrac != -1 || maxFrac != -1;
        boolean explicitMinMaxSig = minSig != -1 || maxSig != -1;
        // Resolve min/max frac for currencies, required for the validation logic and for when minFrac or
        // maxFrac was set (but not both) on a currency instance.
        // NOTE: Increments are handled in "Rounder.constructCurrency()".
        if (useCurrency) {
            if (minFrac == -1 && maxFrac == -1) {
                minFrac = currency.getDefaultFractionDigits(currencyUsage);
                maxFrac = currency.getDefaultFractionDigits(currencyUsage);
            } else if (minFrac == -1) {
                minFrac = Math.min(maxFrac, currency.getDefaultFractionDigits(currencyUsage));
            } else if (maxFrac == -1) {
                maxFrac = Math.max(minFrac, currency.getDefaultFractionDigits(currencyUsage));
            } else {
                // No-op: user override for both minFrac and maxFrac
            }
        }
        // Validate min/max int/frac.
        // For backwards compatibility, minimum overrides maximum if the two conflict.
        if (minInt == 0 && maxFrac != 0) {
            minFrac = (minFrac < 0 || (minFrac == 0 && maxInt == 0)) ? 1 : minFrac;
            maxFrac = maxFrac < 0 ? -1 : maxFrac < minFrac ? minFrac : maxFrac;
            minInt = 0;
            maxInt = maxInt < 0 ? -1 : maxInt > RoundingUtils.MAX_INT_FRAC_SIG ? -1 : maxInt;
        } else {
            // Force a digit before the decimal point.
            minFrac = minFrac < 0 ? 0 : minFrac;
            maxFrac = maxFrac < 0 ? -1 : maxFrac < minFrac ? minFrac : maxFrac;
            minInt = minInt <= 0 ? 1 : minInt > RoundingUtils.MAX_INT_FRAC_SIG ? 1 : minInt;
            maxInt = maxInt < 0 ? -1
                    : maxInt < minInt ? minInt : maxInt > RoundingUtils.MAX_INT_FRAC_SIG ? -1 : maxInt;
        }
        Precision rounding = null;
        if (explicitCurrencyUsage) {
            rounding = Precision.constructCurrency(currencyUsage).withCurrency(currency);
        } else if (roundingIncrement != null) {
            if (PatternStringUtils.ignoreRoundingIncrement(roundingIncrement, maxFrac)) {
                rounding = Precision.constructFraction(minFrac, maxFrac);
            } else {
                rounding = Precision.constructIncrement(roundingIncrement);
            }
        } else if (explicitMinMaxSig) {
            minSig = minSig < 1 ? 1
                    : minSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG : minSig;
            maxSig = maxSig < 0 ? RoundingUtils.MAX_INT_FRAC_SIG
                    : maxSig < minSig ? minSig
                            : maxSig > RoundingUtils.MAX_INT_FRAC_SIG ? RoundingUtils.MAX_INT_FRAC_SIG
                                    : maxSig;
            rounding = Precision.constructSignificant(minSig, maxSig);
        } else if (explicitMinMaxFrac) {
            rounding = Precision.constructFraction(minFrac, maxFrac);
        } else if (useCurrency) {
            rounding = Precision.constructCurrency(currencyUsage);
        }
        if (rounding != null) {
            rounding = rounding.withMode(mathContext);
            macros.precision = rounding;
        }

        ///////////////////
        // INTEGER WIDTH //
        ///////////////////

        macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt);

        ///////////////////////
        // GROUPING STRATEGY //
        ///////////////////////

        macros.grouping = Grouper.forProperties(properties);

        /////////////
        // PADDING //
        /////////////

        if (properties.getFormatWidth() > 0) {
            macros.padder = Padder.forProperties(properties);
        }

        ///////////////////////////////
        // DECIMAL MARK ALWAYS SHOWN //
        ///////////////////////////////

        macros.decimal = properties.getDecimalSeparatorAlwaysShown() ? DecimalSeparatorDisplay.ALWAYS
                : DecimalSeparatorDisplay.AUTO;

        ///////////////////////
        // SIGN ALWAYS SHOWN //
        ///////////////////////

        macros.sign = properties.getSignAlwaysShown() ? SignDisplay.ALWAYS : SignDisplay.AUTO;

        /////////////////////////
        // SCIENTIFIC NOTATION //
        /////////////////////////

        if (properties.getMinimumExponentDigits() != -1) {
            // Scientific notation is required.
            // This whole section feels like a hack, but it is needed for regression tests.
            // The mapping from property bag to scientific notation is nontrivial due to LDML rules.
            if (maxInt > 8) {
                // But #13110: The maximum of 8 digits has unknown origins and is not in the spec.
                // If maxInt is greater than 8, it is set to minInt, even if minInt is greater than 8.
                maxInt = minInt;
                macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt);
            } else if (maxInt > minInt && minInt > 1) {
                // Bug #13289: if maxInt > minInt > 1, then minInt should be 1.
                minInt = 1;
                macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt);
            }
            int engineering = maxInt < 0 ? -1 : maxInt;
            macros.notation = new ScientificNotation(
                    // Engineering interval:
                    engineering,
                    // Enforce minimum integer digits (for patterns like "000.00E0"):
                    (engineering == minInt),
                    // Minimum exponent digits:
                    properties.getMinimumExponentDigits(),
                    // Exponent sign always shown:
                    properties.getExponentSignAlwaysShown() ? SignDisplay.ALWAYS : SignDisplay.AUTO);
            // Scientific notation also involves overriding the rounding mode.
            // TODO: Overriding here is a bit of a hack. Should this logic go earlier?
            if (macros.precision instanceof FractionPrecision) {
                // For the purposes of rounding, get the original min/max int/frac, since the local
                // variables have been manipulated for display purposes.
                int maxInt_ = properties.getMaximumIntegerDigits();
                int minInt_ = properties.getMinimumIntegerDigits();
                int minFrac_ = properties.getMinimumFractionDigits();
                int maxFrac_ = properties.getMaximumFractionDigits();
                if (minInt_ == 0 && maxFrac_ == 0) {
                    // Patterns like "#E0" and "##E0", which mean no rounding!
                    macros.precision = Precision.constructInfinite().withMode(mathContext);
                } else if (minInt_ == 0 && minFrac_ == 0) {
                    // Patterns like "#.##E0" (no zeros in the mantissa), which mean round to maxFrac+1
                    macros.precision = Precision.constructSignificant(1, maxFrac_ + 1).withMode(mathContext);
                } else {
                    int maxSig_ = minInt_ + maxFrac_;
                    // Bug #20058: if maxInt_ > minInt_ > 1, then minInt_ should be 1.
                    if (maxInt_ > minInt_ && minInt_ > 1) {
                        minInt_ = 1;
                    }
                    int minSig_ = minInt_ + minFrac_;
                    // To avoid regression, maxSig is not reset when minInt_ set to 1.
                    // TODO: Reset maxSig_ = 1 + minFrac_ to follow the spec.
                    macros.precision = Precision.constructSignificant(minSig_, maxSig_)
                            .withMode(mathContext);
                }
            }
        }

        //////////////////////
        // COMPACT NOTATION //
        //////////////////////

        if (properties.getCompactStyle() != null) {
            if (properties.getCompactCustomData() != null) {
                macros.notation = new CompactNotation(properties.getCompactCustomData());
            } else if (properties.getCompactStyle() == CompactStyle.LONG) {
                macros.notation = Notation.compactLong();
            } else {
                macros.notation = Notation.compactShort();
            }
            // Do not forward the affix provider.
            macros.affixProvider = null;
        }

        /////////////////
        // MULTIPLIERS //
        /////////////////

        macros.scale = RoundingUtils.scaleFromProperties(properties);

        //////////////////////
        // PROPERTY EXPORTS //
        //////////////////////

        if (exportedProperties != null) {

            exportedProperties.setCurrency(currency);
            exportedProperties.setMathContext(mathContext);
            exportedProperties.setRoundingMode(mathContext.getRoundingMode());
            exportedProperties.setMinimumIntegerDigits(minInt);
            exportedProperties.setMaximumIntegerDigits(maxInt == -1 ? Integer.MAX_VALUE : maxInt);

            Precision rounding_;
            if (rounding instanceof CurrencyPrecision) {
                rounding_ = ((CurrencyPrecision) rounding).withCurrency(currency);
            } else {
                rounding_ = rounding;
            }
            int minFrac_ = minFrac;
            int maxFrac_ = maxFrac;
            int minSig_ = minSig;
            int maxSig_ = maxSig;
            BigDecimal increment_ = null;
            if (rounding_ instanceof FractionRounderImpl) {
                minFrac_ = ((FractionRounderImpl) rounding_).minFrac;
                maxFrac_ = ((FractionRounderImpl) rounding_).maxFrac;
            } else if (rounding_ instanceof IncrementRounderImpl) {
                increment_ = ((IncrementRounderImpl) rounding_).increment;
                minFrac_ = increment_.scale();
                maxFrac_ = increment_.scale();
            } else if (rounding_ instanceof SignificantRounderImpl) {
                minSig_ = ((SignificantRounderImpl) rounding_).minSig;
                maxSig_ = ((SignificantRounderImpl) rounding_).maxSig;
            }

            exportedProperties.setMinimumFractionDigits(minFrac_);
            exportedProperties.setMaximumFractionDigits(maxFrac_);
            exportedProperties.setMinimumSignificantDigits(minSig_);
            exportedProperties.setMaximumSignificantDigits(maxSig_);
            exportedProperties.setRoundingIncrement(increment_);
        }

        return macros;
    }
}
