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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import com.ibm.icu.util.BytesTrie;
import com.ibm.icu.util.CharsTrie;
import com.ibm.icu.util.CharsTrieBuilder;
import com.ibm.icu.util.ICUCloneNotSupportedException;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.StringTrieBuilder;

public class MeasureUnitImpl {

    /**
     * The full unit identifier.  Null if not computed.
     */
    private String identifier = null;

    /**
     * The complexity, either SINGLE, COMPOUND, or MIXED.
     */
    private MeasureUnit.Complexity complexity = MeasureUnit.Complexity.SINGLE;

    /**
     * The list of simple units. These may be summed or multiplied, based on the
     * value of the complexity field.
     * <p>
     * The "dimensionless" unit (SingleUnitImpl default constructor) must not be
     * added to this list.
     * <p>
     * The "dimensionless" <code>MeasureUnitImpl</code> has an empty <code>singleUnits</code>.
     */
    private ArrayList<SingleUnitImpl> singleUnits;

    public MeasureUnitImpl() {
        singleUnits = new ArrayList<>();
    }

    public MeasureUnitImpl(SingleUnitImpl singleUnit) {
        this();
        this.appendSingleUnit(singleUnit);
    }

    /**
     * Parse a unit identifier into a MeasureUnitImpl.
     *
     * @param identifier The unit identifier string.
     * @return A newly parsed object.
     * @throws IllegalArgumentException in case of incorrect/non-parsed identifier.
     */
    public static MeasureUnitImpl forIdentifier(String identifier) {
        return UnitsParser.parseForIdentifier(identifier);
    }

    /**
     * Used for currency units.
     */
    public static MeasureUnitImpl forCurrencyCode(String currencyCode) {
        MeasureUnitImpl result = new MeasureUnitImpl();
        result.identifier = currencyCode;
        return result;
    }

    public MeasureUnitImpl copy() {
        MeasureUnitImpl result = new MeasureUnitImpl();
        result.complexity = this.complexity;
        result.identifier = this.identifier;
        for (SingleUnitImpl single : this.singleUnits) {
            result.singleUnits.add(single.copy());
        }
        return result;
    }

    /**
     * Returns the list of simple units.
     */
    public ArrayList<SingleUnitImpl> getSingleUnits() {
        return singleUnits;
    }

    /**
     * Mutates this MeasureUnitImpl to take the reciprocal.
     */
    public void takeReciprocal() {
        this.identifier = null;
        for (SingleUnitImpl singleUnit :
                this.singleUnits) {
            singleUnit.setDimensionality(singleUnit.getDimensionality() * -1);
        }
    }

    /**
     * Extracts the list of all the individual units inside the `MeasureUnitImpl`.
     * For example:
     * -   if the <code>MeasureUnitImpl</code> is <code>foot-per-hour</code>
     * it will return a list of 1 <code>{foot-per-hour}</code>
     * -   if the <code>MeasureUnitImpl</code> is <code>foot-and-inch</code>
     * it will return a list of 2 <code>{ foot, inch}</code>
     *
     * @return a list of <code>MeasureUnitImpl</code>
     */
    public ArrayList<MeasureUnitImpl> extractIndividualUnits() {
        ArrayList<MeasureUnitImpl> result = new ArrayList<>();
        if (this.getComplexity() == MeasureUnit.Complexity.MIXED) {
            // In case of mixed units, each single unit can be considered as a stand alone MeasureUnitImpl.
            for (SingleUnitImpl singleUnit :
                    this.getSingleUnits()) {
                result.add(new MeasureUnitImpl(singleUnit));
            }

            return result;
        }

        result.add(this.copy());
        return result;
    }

    /**
     * Applies dimensionality to all the internal single units.
     * For example: <b>square-meter-per-second</b>, when we apply dimensionality -2, it will be <b>square-second-per-p4-meter</b>
     */
    public void applyDimensionality(int dimensionality) {
        for (SingleUnitImpl singleUnit :
                singleUnits) {
            singleUnit.setDimensionality(singleUnit.getDimensionality() * dimensionality);
        }
    }

    /**
     * Mutates this MeasureUnitImpl to append a single unit.
     *
     * @return true if a new item was added. If unit is the dimensionless unit,
     * it is never added: the return value will always be false.
     */
    public boolean appendSingleUnit(SingleUnitImpl singleUnit) {
        identifier = null;

        if (singleUnit == null) {
            // We don't append dimensionless units.
            return false;
        }

        // Find a similar unit that already exists, to attempt to coalesce
        SingleUnitImpl oldUnit = null;
        for (int i = 0, n = this.singleUnits.size(); i < n; i++) {
            SingleUnitImpl candidate = this.singleUnits.get(i);
            if (candidate.isCompatibleWith(singleUnit)) {
                oldUnit = candidate;
                break;
            }
        }

        if (oldUnit != null) {
            // Both dimensionalities will be positive, or both will be negative, by
            // virtue of isCompatibleWith().
            oldUnit.setDimensionality(oldUnit.getDimensionality() + singleUnit.getDimensionality());

            return false;
        }

        // Add a copy of singleUnit
        this.singleUnits.add(singleUnit.copy());

        // If the MeasureUnitImpl is `UMEASURE_UNIT_SINGLE` and after the appending a unit, the singleUnits are more
        // than one singleUnit. thus means the complexity should be `UMEASURE_UNIT_COMPOUND`
        if (this.singleUnits.size() > 1 && this.complexity == MeasureUnit.Complexity.SINGLE) {
            this.setComplexity(MeasureUnit.Complexity.COMPOUND);
        }

        return true;
    }

    /**
     * Transform this MeasureUnitImpl into a MeasureUnit, simplifying if possible.
     * <p>
     * NOTE: this function must be called from a thread-safe class
     */
    public MeasureUnit build() {
        return MeasureUnit.fromMeasureUnitImpl(this);
    }

    /**
     * @return SingleUnitImpl
     * @throws UnsupportedOperationException if the object could not be converted to SingleUnitImpl.
     */
    public SingleUnitImpl getSingleUnitImpl() {
        if (this.singleUnits.size() == 0) {
            return new SingleUnitImpl();
        }
        if (this.singleUnits.size() == 1) {
            return this.singleUnits.get(0).copy();
        }

        throw new UnsupportedOperationException();
    }


    /**
     * Returns the CLDR unit identifier and null if not computed.
     */
    public String getIdentifier() {
        return identifier;
    }

    public MeasureUnit.Complexity getComplexity() {
        return complexity;
    }

    public void setComplexity(MeasureUnit.Complexity complexity) {
        this.complexity = complexity;
    }

    /**
     * Normalizes the MeasureUnitImpl and generates the identifier string in place.
     */
    public void serialize() {
        if (this.getSingleUnits().size() == 0) {
            // Dimensionless, constructed by the default constructor: no appending
            // to this.result, we wish it to contain the zero-length string.
            return;
        }
        if (this.complexity == MeasureUnit.Complexity.COMPOUND) {
            // Note: don't sort a MIXED unit
            Collections.sort(this.getSingleUnits(), new SingleUnitComparator());
        }

        StringBuilder result = new StringBuilder();
        boolean beforePer = true;
        boolean firstTimeNegativeDimension = false;
        for (SingleUnitImpl singleUnit :
                this.getSingleUnits()) {
            if (beforePer && singleUnit.getDimensionality() < 0) {
                beforePer = false;
                firstTimeNegativeDimension = true;
            } else if (singleUnit.getDimensionality() < 0) {
                firstTimeNegativeDimension = false;
            }

            String singleUnitIdentifier = singleUnit.getNeutralIdentifier();
            if (this.getComplexity() == MeasureUnit.Complexity.MIXED) {
                if (result.length() != 0) {
                    result.append("-and-");
                }
            } else {
                if (firstTimeNegativeDimension) {
                    if (result.length() == 0) {
                        result.append("per-");
                    } else {
                        result.append("-per-");
                    }
                } else {
                    if (result.length() != 0) {
                        result.append("-");
                    }
                }
            }

            result.append(singleUnitIdentifier);
        }

        this.identifier = result.toString();
    }

    public enum CompoundPart {
        // Represents "-per-"
        PER(0),
        // Represents "-"
        TIMES(1),
        // Represents "-and-"
        AND(2);

        private final int index;

        CompoundPart(int index) {
            this.index = index;
        }

        public static CompoundPart getCompoundPartFromTrieIndex(int trieIndex) {
            int index = trieIndex - UnitsData.Constants.kCompoundPartOffset;
            switch (index) {
                case 0:
                    return CompoundPart.PER;
                case 1:
                    return CompoundPart.TIMES;
                case 2:
                    return CompoundPart.AND;
                default:
                    throw new AssertionError("CompoundPart index must be 0, 1 or 2");
            }
        }

        public int getTrieIndex() {
            return this.index + UnitsData.Constants.kCompoundPartOffset;
        }

        public int getValue() {
            return index;
        }
    }

    public enum PowerPart {
        P2(2),
        P3(3),
        P4(4),
        P5(5),
        P6(6),
        P7(7),
        P8(8),
        P9(9),
        P10(10),
        P11(11),
        P12(12),
        P13(13),
        P14(14),
        P15(15);

        private final int power;

        PowerPart(int power) {
            this.power = power;
        }

        public static int getPowerFromTrieIndex(int trieIndex) {
            return trieIndex - UnitsData.Constants.kPowerPartOffset;
        }

        public int getTrieIndex() {
            return this.power + UnitsData.Constants.kPowerPartOffset;
        }

        public int getValue() {
            return power;
        }
    }

    public enum InitialCompoundPart {

        // Represents "per-", the only compound part that can appear at the start of
        // an identifier.
        INITIAL_COMPOUND_PART_PER(0);

        private final int index;

        InitialCompoundPart(int powerIndex) {
            this.index = powerIndex;
        }

        public static InitialCompoundPart getInitialCompoundPartFromTrieIndex(int trieIndex) {
            int index = trieIndex - UnitsData.Constants.kInitialCompoundPartOffset;
            if (index == 0) {
                return INITIAL_COMPOUND_PART_PER;
            }

            throw new IllegalArgumentException("Incorrect trieIndex");
        }

        public int getTrieIndex() {
            return this.index + UnitsData.Constants.kInitialCompoundPartOffset;
        }

        public int getValue() {
            return index;
        }

    }

    public static class UnitsParser {
        // This used only to not build the trie each time we use the parser
        private volatile static CharsTrie savedTrie = null;
        private final String[] simpleUnits;
        // This trie used in the parsing operation.
        private CharsTrie trie;
        // Tracks parser progress: the offset into fSource.
        private int fIndex = 0;
        // Set to true when we've seen a "-per-" or a "per-", after which all units
        // are in the denominator. Until we find an "-and-", at which point the
        // identifier is invalid pending TODO(CLDR-13700).
        private boolean fAfterPer = false;
        private String fSource;
        // If an "-and-" was parsed prior to finding the "single
        //     * unit", sawAnd is set to true. If not, it is left as is.
        private boolean fSawAnd = false;

        private UnitsParser(String identifier) {
            this.simpleUnits = UnitsData.getSimpleUnits();
            this.fSource = identifier;

            if (UnitsParser.savedTrie != null) {
                try {
                    this.trie = UnitsParser.savedTrie.clone();
                } catch (CloneNotSupportedException e) {
                    throw new ICUCloneNotSupportedException();
                }
                return;
            }

            // Building the trie.
            CharsTrieBuilder trieBuilder;
            trieBuilder = new CharsTrieBuilder();

            // Add syntax parts (compound, power prefixes)
            trieBuilder.add("-per-", CompoundPart.PER.getTrieIndex());
            trieBuilder.add("-", CompoundPart.TIMES.getTrieIndex());
            trieBuilder.add("-and-", CompoundPart.AND.getTrieIndex());
            trieBuilder.add("per-", InitialCompoundPart.INITIAL_COMPOUND_PART_PER.getTrieIndex());
            trieBuilder.add("square-", PowerPart.P2.getTrieIndex());
            trieBuilder.add("cubic-", PowerPart.P3.getTrieIndex());
            trieBuilder.add("pow2-", PowerPart.P2.getTrieIndex());
            trieBuilder.add("pow3-", PowerPart.P3.getTrieIndex());
            trieBuilder.add("pow4-", PowerPart.P4.getTrieIndex());
            trieBuilder.add("pow5-", PowerPart.P5.getTrieIndex());
            trieBuilder.add("pow6-", PowerPart.P6.getTrieIndex());
            trieBuilder.add("pow7-", PowerPart.P7.getTrieIndex());
            trieBuilder.add("pow8-", PowerPart.P8.getTrieIndex());
            trieBuilder.add("pow9-", PowerPart.P9.getTrieIndex());
            trieBuilder.add("pow10-", PowerPart.P10.getTrieIndex());
            trieBuilder.add("pow11-", PowerPart.P11.getTrieIndex());
            trieBuilder.add("pow12-", PowerPart.P12.getTrieIndex());
            trieBuilder.add("pow13-", PowerPart.P13.getTrieIndex());
            trieBuilder.add("pow14-", PowerPart.P14.getTrieIndex());
            trieBuilder.add("pow15-", PowerPart.P15.getTrieIndex());

            // Add SI prefixes
            for (MeasureUnit.SIPrefix siPrefix :
                    MeasureUnit.SIPrefix.values()) {
                trieBuilder.add(siPrefix.getIdentifier(), getTrieIndex(siPrefix));
            }

            // Add simple units
            for (int i = 0; i < simpleUnits.length; i++) {
                trieBuilder.add(simpleUnits[i], i + UnitsData.Constants.kSimpleUnitOffset);

            }

            // TODO: Use SLOW or FAST here?
            UnitsParser.savedTrie = trieBuilder.build(StringTrieBuilder.Option.FAST);

            try {
                this.trie = UnitsParser.savedTrie.clone();
            } catch (CloneNotSupportedException e) {
                throw new ICUCloneNotSupportedException();
            }
        }


        /**
         * Construct a MeasureUnit from a CLDR Unit Identifier, defined in UTS 35.
         * Validates and canonicalizes the identifier.
         *
         * @return MeasureUnitImpl object or null if the identifier is empty.
         * @throws IllegalArgumentException in case of invalid identifier.
         */
        public static MeasureUnitImpl parseForIdentifier(String identifier) {
            if (identifier == null || identifier.isEmpty()) {
                return null;
            }

            UnitsParser parser = new UnitsParser(identifier);
            return parser.parse();

        }

        private static MeasureUnit.SIPrefix getSiPrefixFromTrieIndex(int trieIndex) {
            for (MeasureUnit.SIPrefix element :
                    MeasureUnit.SIPrefix.values()) {
                if (getTrieIndex(element) == trieIndex)
                    return element;
            }

            throw new IllegalArgumentException("Incorrect trieIndex");
        }

        private static int getTrieIndex(MeasureUnit.SIPrefix prefix) {
            return prefix.getPower() + UnitsData.Constants.kSIPrefixOffset;
        }

        private MeasureUnitImpl parse() {
            MeasureUnitImpl result = new MeasureUnitImpl();

            if (fSource.isEmpty()) {
                // The dimensionless unit: nothing to parse. return null.
                return null;
            }

            while (hasNext()) {
                fSawAnd = false;
                SingleUnitImpl singleUnit = nextSingleUnit();

                boolean added = result.appendSingleUnit(singleUnit);
                if (fSawAnd && !added) {
                    throw new IllegalArgumentException("Two similar units are not allowed in a mixed unit.");
                }

                if ((result.singleUnits.size()) >= 2) {
                    // nextSingleUnit fails appropriately for "per" and "and" in the
                    // same identifier. It doesn't fail for other compound units
                    // (COMPOUND_PART_TIMES). Consequently we take care of that
                    // here.
                    MeasureUnit.Complexity complexity =
                            fSawAnd ? MeasureUnit.Complexity.MIXED : MeasureUnit.Complexity.COMPOUND;
                    if (result.getSingleUnits().size() == 2) {
                        // After appending two singleUnits, the complexity will be `UMEASURE_UNIT_COMPOUND`
                        assert result.getComplexity() == MeasureUnit.Complexity.COMPOUND;
                        result.setComplexity(complexity);
                    } else if (result.getComplexity() != complexity) {
                        throw new IllegalArgumentException("Can't have mixed compound units");
                    }
                }
            }

            return result;
        }

        /**
         * Returns the next "single unit" via result.
         * <p>
         * If a "-per-" was parsed, the result will have appropriate negative
         * dimensionality.
         * <p>
         *
         * @throws IllegalArgumentException if we parse both compound units and "-and-", since mixed
         *                                  compound units are not yet supported - TODO(CLDR-13700).
         */
        private SingleUnitImpl nextSingleUnit() {
            SingleUnitImpl result = new SingleUnitImpl();

            // state:
            // 0 = no tokens seen yet (will accept power, SI prefix, or simple unit)
            // 1 = power token seen (will not accept another power token)
            // 2 = SI prefix token seen (will not accept a power or SI prefix token)
            int state = 0;

            boolean atStart = fIndex == 0;
            Token token = nextToken();

            if (atStart) {
                // Identifiers optionally start with "per-".
                if (token.getType() == Token.Type.TYPE_INITIAL_COMPOUND_PART) {
                    assert token.getInitialCompoundPart() == InitialCompoundPart.INITIAL_COMPOUND_PART_PER;

                    fAfterPer = true;
                    result.setDimensionality(-1);

                    token = nextToken();
                }
            } else {
                // All other SingleUnit's are separated from previous SingleUnit's
                // via a compound part:
                if (token.getType() != Token.Type.TYPE_COMPOUND_PART) {
                    throw new IllegalArgumentException("token type must be TYPE_COMPOUND_PART");
                }

                CompoundPart compoundPart = CompoundPart.getCompoundPartFromTrieIndex(token.getMatch());
                switch (compoundPart) {
                    case PER:
                        if (fSawAnd) {
                            throw new IllegalArgumentException("Mixed compound units not yet supported");
                            // TODO(CLDR-13700).
                        }

                        fAfterPer = true;
                        result.setDimensionality(-1);
                        break;

                    case TIMES:
                        if (fAfterPer) {
                            result.setDimensionality(-1);
                        }
                        break;

                    case AND:
                        if (fAfterPer) {
                            // not yet supported, TODO(CLDR-13700).
                            throw new IllegalArgumentException("Can't start with \"-and-\", and mixed compound units");
                        }
                        fSawAnd = true;
                        break;
                }

                token = nextToken();
            }

            // Read tokens until we have a complete SingleUnit or we reach the end.
            while (true) {
                switch (token.getType()) {
                    case TYPE_POWER_PART:
                        if (state > 0) {
                            throw new IllegalArgumentException();
                        }

                        result.setDimensionality(result.getDimensionality() * token.getPower());
                        state = 1;
                        break;

                    case TYPE_SI_PREFIX:
                        if (state > 1) {
                            throw new IllegalArgumentException();
                        }

                        result.setSiPrefix(token.getSIPrefix());
                        state = 2;
                        break;

                    case TYPE_SIMPLE_UNIT:
                        result.setSimpleUnit(token.getSimpleUnitIndex(), simpleUnits);
                        return result;

                    default:
                        throw new IllegalArgumentException();
                }

                if (!hasNext()) {
                    throw new IllegalArgumentException("We ran out of tokens before finding a complete single unit.");
                }

                token = nextToken();
            }
        }

        private boolean hasNext() {
            return fIndex < fSource.length();
        }

        private Token nextToken() {
            trie.reset();
            int match = -1;
            // Saves the position in the fSource string for the end of the most
            // recent matching token.
            int previ = -1;

            // Find the longest token that matches a value in the trie:
            while (fIndex < fSource.length()) {
                BytesTrie.Result result = trie.next(fSource.charAt(fIndex++));
                if (result == BytesTrie.Result.NO_MATCH) {
                    break;
                } else if (result == BytesTrie.Result.NO_VALUE) {
                    continue;
                }

                match = trie.getValue();
                previ = fIndex;

                if (result == BytesTrie.Result.FINAL_VALUE) {
                    break;
                }

                if (result != BytesTrie.Result.INTERMEDIATE_VALUE) {
                    throw new IllegalArgumentException("result must has an intermediate value");
                }

                // continue;
            }


            if (match < 0) {
                throw new IllegalArgumentException("Encountered unknown token starting at index " + previ);
            } else {
                fIndex = previ;
            }

            return new Token(match);
        }

        static class Token {

            private final int fMatch;
            private final Type type;

            public Token(int fMatch) {
                this.fMatch = fMatch;
                type = calculateType(fMatch);
            }

            public Type getType() {
                return this.type;
            }

            public MeasureUnit.SIPrefix getSIPrefix() {
                assert this.type == Type.TYPE_SI_PREFIX;
                return getSiPrefixFromTrieIndex(this.fMatch);
            }

            // Valid only for tokens with type TYPE_COMPOUND_PART.
            public int getMatch() {
                assert getType() == Type.TYPE_COMPOUND_PART;
                return fMatch;
            }

            // Even if there is only one InitialCompoundPart value, we have this
            // function for the simplicity of code consistency.
            public InitialCompoundPart getInitialCompoundPart() {
                assert (this.type == Type.TYPE_INITIAL_COMPOUND_PART
                        &&
                        fMatch == InitialCompoundPart.INITIAL_COMPOUND_PART_PER.getTrieIndex());
                return InitialCompoundPart.getInitialCompoundPartFromTrieIndex(fMatch);
            }

            public int getPower() {
                assert this.type == Type.TYPE_POWER_PART;
                return PowerPart.getPowerFromTrieIndex(this.fMatch);
            }

            public int getSimpleUnitIndex() {
                return this.fMatch - UnitsData.Constants.kSimpleUnitOffset;
            }

            // Calling calculateType() is invalid, resulting in an assertion failure, if Token
            // value isn't positive.
            private Type calculateType(int fMatch) {
                if (fMatch <= 0) {
                    throw new AssertionError("fMatch must have a positive value");
                }

                if (fMatch < UnitsData.Constants.kCompoundPartOffset) {
                    return Type.TYPE_SI_PREFIX;
                }
                if (fMatch < UnitsData.Constants.kInitialCompoundPartOffset) {
                    return Type.TYPE_COMPOUND_PART;
                }
                if (fMatch < UnitsData.Constants.kPowerPartOffset) {
                    return Type.TYPE_INITIAL_COMPOUND_PART;
                }
                if (fMatch < UnitsData.Constants.kSimpleUnitOffset) {
                    return Type.TYPE_POWER_PART;
                }

                return Type.TYPE_SIMPLE_UNIT;
            }

            enum Type {
                TYPE_UNDEFINED,
                TYPE_SI_PREFIX,
                // Token type for "-per-", "-", and "-and-".
                TYPE_COMPOUND_PART,
                // Token type for "per-".
                TYPE_INITIAL_COMPOUND_PART,
                TYPE_POWER_PART,
                TYPE_SIMPLE_UNIT,
            }
        }
    }

    static class MeasureUnitImplComparator implements Comparator<MeasureUnitImpl> {
        private ConversionRates conversionRates;

        public MeasureUnitImplComparator(ConversionRates conversionRates) {
            this.conversionRates = conversionRates;
        }

        @Override
        public int compare(MeasureUnitImpl o1, MeasureUnitImpl o2) {
            UnitConverter fromO1toO2 = new UnitConverter(o1, o2, conversionRates);
            return fromO1toO2.convert(BigDecimal.valueOf(1)).compareTo(BigDecimal.valueOf(1));
        }
    }

    static class SingleUnitComparator implements Comparator<SingleUnitImpl> {
        @Override
        public int compare(SingleUnitImpl o1, SingleUnitImpl o2) {
            return o1.compareTo(o2);
        }
    }

    @Override
    public String toString() {
        return "MeasureUnitImpl [" + build().getIdentifier() + "]";
    }
}
