/*
**********************************************************************
*   Copyright (c) 2002-2011, International Business Machines Corporation
*   and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   01/14/2002  aliu        Creation.
**********************************************************************
*/

package com.ibm.icu.text;

import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ibm.icu.impl.PatternProps;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.util.CaseInsensitiveString;

/**
 * Parsing component for transliterator IDs.  This class contains only
 * static members; it cannot be instantiated.  Methods in this class
 * parse various ID formats, including the following:
 *
 * A basic ID, which contains source, target, and variant, but no
 * filter and no explicit inverse.  Examples include
 * "Latin-Greek/UNGEGN" and "Null".
 *
 * A single ID, which is a basic ID plus optional filter and optional
 * explicit inverse.  Examples include "[a-zA-Z] Latin-Greek" and
 * "Lower (Upper)".
 *
 * A compound ID, which is a sequence of one or more single IDs,
 * separated by semicolons, with optional forward and reverse global
 * filters.  The global filters are UnicodeSet patterns prepended or
 * appended to the IDs, separated by semicolons.  An appended filter
 * must be enclosed in parentheses and applies in the reverse
 * direction.
 *
 * @author Alan Liu
 */
class TransliteratorIDParser {

    private static final char ID_DELIM = ';';

    private static final char TARGET_SEP = '-';

    private static final char VARIANT_SEP = '/';

    private static final char OPEN_REV = '(';

    private static final char CLOSE_REV = ')';

    private static final String ANY = "Any";

    private static final int FORWARD = Transliterator.FORWARD;

    private static final int REVERSE = Transliterator.REVERSE;

    private static final Map<CaseInsensitiveString, String> SPECIAL_INVERSES =
        Collections.synchronizedMap(new HashMap<CaseInsensitiveString, String>());

    /**
     * A structure containing the parsed data of a filtered ID, that
     * is, a basic ID optionally with a filter.
     *
     * 'source' and 'target' will always be non-null.  The 'variant'
     * will be non-null only if a non-empty variant was parsed.
     *
     * 'sawSource' is true if there was an explicit source in the
     * parsed id.  If there was no explicit source, then an implied
     * source of ANY is returned and 'sawSource' is set to false.
     * 
     * 'filter' is the parsed filter pattern, or null if there was no
     * filter.
     */
    private static class Specs {
        public String source; // not null
        public String target; // not null
        public String variant; // may be null
        public String filter; // may be null
        public boolean sawSource;
        Specs(String s, String t, String v, boolean sawS, String f) {
            source = s;
            target = t;
            variant = v;
            sawSource = sawS;
            filter = f;
        }
    }

    /**
     * A structure containing the canonicalized data of a filtered ID,
     * that is, a basic ID optionally with a filter.
     *
     * 'canonID' is always non-null.  It may be the empty string "".
     * It is the id that should be assigned to the created
     * transliterator.  It _cannot_ be instantiated directly.
     *
     * 'basicID' is always non-null and non-empty.  It is always of
     * the form S-T or S-T/V.  It is designed to be fed to low-level
     * instantiation code that only understands these two formats.
     *
     * 'filter' may be null, if there is none, or non-null and
     * non-empty.
     */
    static class SingleID {
        public String canonID;
        public String basicID;
        public String filter;
        SingleID(String c, String b, String f) {
            canonID = c;
            basicID = b;
            filter = f;
        }
        SingleID(String c, String b) {
            this(c, b, null);
        }
        Transliterator getInstance() {
            Transliterator t;
            if (basicID == null || basicID.length() == 0) {
                t = Transliterator.getBasicInstance("Any-Null", canonID);
            } else {
                t = Transliterator.getBasicInstance(basicID, canonID);
            }
            if (t != null) {
                if (filter != null) {
                    t.setFilter(new UnicodeSet(filter));
                }
            }
            return t;
        }
    }

    /**
     * Parse a filter ID, that is, an ID of the general form
     * "[f1] s1-t1/v1", with the filters optional, and the variants optional.
     * @param id the id to be parsed
     * @param pos INPUT-OUTPUT parameter.  On input, the position of
     * the first character to parse.  On output, the position after
     * the last character parsed.
     * @return a SingleID object or null if the parse fails
     */
    public static SingleID parseFilterID(String id, int[] pos) {

        int start = pos[0];
        Specs specs = parseFilterID(id, pos, true);
        if (specs == null) {
            pos[0] = start;
            return null;
        }

        // Assemble return results
        SingleID single = specsToID(specs, FORWARD);
        single.filter = specs.filter;
        return single;
    }

    /**
     * Parse a single ID, that is, an ID of the general form
     * "[f1] s1-t1/v1 ([f2] s2-t3/v2)", with the parenthesized element
     * optional, the filters optional, and the variants optional.
     * @param id the id to be parsed
     * @param pos INPUT-OUTPUT parameter.  On input, the position of
     * the first character to parse.  On output, the position after
     * the last character parsed.
     * @param dir the direction.  If the direction is REVERSE then the
     * SingleID is constructed for the reverse direction.
     * @return a SingleID object or null
     */
    public static SingleID parseSingleID(String id, int[] pos, int dir) {

        int start = pos[0];

        // The ID will be of the form A, A(), A(B), or (B), where
        // A and B are filter IDs.
        Specs specsA = null;
        Specs specsB = null;
        boolean sawParen = false;

        // On the first pass, look for (B) or ().  If this fails, then
        // on the second pass, look for A, A(B), or A().
        for (int pass=1; pass<=2; ++pass) {
            if (pass == 2) {
                specsA = parseFilterID(id, pos, true);
                if (specsA == null) {
                    pos[0] = start;
                    return null;
                }
            }
            if (Utility.parseChar(id, pos, OPEN_REV)) {
                sawParen = true;
                if (!Utility.parseChar(id, pos, CLOSE_REV)) {
                    specsB = parseFilterID(id, pos, true);
                    // Must close with a ')'
                    if (specsB == null || !Utility.parseChar(id, pos, CLOSE_REV)) {
                        pos[0] = start;
                        return null;
                    }
                }
                break;
            }
        }

        // Assemble return results
        SingleID single;
        if (sawParen) {
            if (dir == FORWARD) {
                single = specsToID(specsA, FORWARD);
                single.canonID = single.canonID +
                    OPEN_REV + specsToID(specsB, FORWARD).canonID + CLOSE_REV;
                if (specsA != null) {
                    single.filter = specsA.filter;
                }
            } else {
                single = specsToID(specsB, FORWARD);
                single.canonID = single.canonID +
                    OPEN_REV + specsToID(specsA, FORWARD).canonID + CLOSE_REV;
                if (specsB != null) {
                    single.filter = specsB.filter;
                }
            }
        } else {
            // assert(specsA != null);
            if (dir == FORWARD) {
                single = specsToID(specsA, FORWARD);
            } else {
                single = specsToSpecialInverse(specsA);
                if (single == null) {
                    single = specsToID(specsA, REVERSE);
                }
            }
            single.filter = specsA.filter;
        }

        return single;
    }

    /**
     * Parse a global filter of the form "[f]" or "([f])", depending
     * on 'withParens'.
     * @param id the pattern the parse
     * @param pos INPUT-OUTPUT parameter.  On input, the position of
     * the first character to parse.  On output, the position after
     * the last character parsed.
     * @param dir the direction.
     * @param withParens INPUT-OUTPUT parameter.  On entry, if
     * withParens[0] is 0, then parens are disallowed.  If it is 1,
     * then parens are requires.  If it is -1, then parens are
     * optional, and the return result will be set to 0 or 1.
     * @param canonID OUTPUT parameter.  The pattern for the filter
     * added to the canonID, either at the end, if dir is FORWARD, or
     * at the start, if dir is REVERSE.  The pattern will be enclosed
     * in parentheses if appropriate, and will be suffixed with an
     * ID_DELIM character.  May be null.
     * @return a UnicodeSet object or null.  A non-null results
     * indicates a successful parse, regardless of whether the filter
     * applies to the given direction.  The caller should discard it
     * if withParens != (dir == REVERSE).
     */
    public static UnicodeSet parseGlobalFilter(String id, int[] pos, int dir,
                                               int[] withParens,
                                               StringBuffer canonID) {
        UnicodeSet filter = null;
        int start = pos[0];

        if (withParens[0] == -1) {
            withParens[0] = Utility.parseChar(id, pos, OPEN_REV) ? 1 : 0;
        } else if (withParens[0] == 1) {
            if (!Utility.parseChar(id, pos, OPEN_REV)) {
                pos[0] = start;
                return null;
            }
        }
        
        pos[0] = PatternProps.skipWhiteSpace(id, pos[0]);

        if (UnicodeSet.resemblesPattern(id, pos[0])) {
            ParsePosition ppos = new ParsePosition(pos[0]);
            try {
                filter = new UnicodeSet(id, ppos, null);
            } catch (IllegalArgumentException e) {
                pos[0] = start;
                return null;
            }

            String pattern = id.substring(pos[0], ppos.getIndex());
            pos[0] = ppos.getIndex();

            if (withParens[0] == 1 && !Utility.parseChar(id, pos, CLOSE_REV)) {
                pos[0] = start;
                return null;
            }

            // In the forward direction, append the pattern to the
            // canonID.  In the reverse, insert it at zero, and invert
            // the presence of parens ("A" <-> "(A)").
            if (canonID != null) {
                if (dir == FORWARD) {
                    if (withParens[0] == 1) {
                        pattern = String.valueOf(OPEN_REV) + pattern + CLOSE_REV;
                    }
                    canonID.append(pattern + ID_DELIM);
                } else {
                    if (withParens[0] == 0) {
                        pattern = String.valueOf(OPEN_REV) + pattern + CLOSE_REV;
                    }
                    canonID.insert(0, pattern + ID_DELIM);
                }
            }
        }

        return filter;
    }

    /**
     * Parse a compound ID, consisting of an optional forward global
     * filter, a separator, one or more single IDs delimited by
     * separators, an an optional reverse global filter.  The
     * separator is a semicolon.  The global filters are UnicodeSet
     * patterns.  The reverse global filter must be enclosed in
     * parentheses.
     * @param id the pattern the parse
     * @param dir the direction.
     * @param canonID OUTPUT parameter that receives the canonical ID,
     * consisting of canonical IDs for all elements, as returned by
     * parseSingleID(), separated by semicolons.  Previous contents
     * are discarded.
     * @param list OUTPUT parameter that receives a list of SingleID
     * objects representing the parsed IDs.  Previous contents are
     * discarded.
     * @param globalFilter OUTPUT parameter that receives a pointer to
     * a newly created global filter for this ID in this direction, or
     * null if there is none.
     * @return true if the parse succeeds, that is, if the entire
     * id is consumed without syntax error.
     */
    public static boolean parseCompoundID(String id, int dir,
                                          StringBuffer canonID,
                                          List<SingleID> list,
                                          UnicodeSet[] globalFilter) {
        int[] pos = new int[] { 0 };
        int[] withParens = new int[1];
        list.clear();
        UnicodeSet filter;
        globalFilter[0] = null;
        canonID.setLength(0);

        // Parse leading global filter, if any
        withParens[0] = 0; // parens disallowed
        filter = parseGlobalFilter(id, pos, dir, withParens, canonID);
        if (filter != null) {
            if (!Utility.parseChar(id, pos, ID_DELIM)) {
                // Not a global filter; backup and resume
                canonID.setLength(0);
                pos[0] = 0;
            }
            if (dir == FORWARD) {
                globalFilter[0] = filter;
            }
        }

        boolean sawDelimiter = true;
        for (;;) {
            SingleID single = parseSingleID(id, pos, dir);
            if (single == null) {
                break;
            }
            if (dir == FORWARD) {
                list.add(single);
            } else {
                list.add(0, single);
            }
            if (!Utility.parseChar(id, pos, ID_DELIM)) {
                sawDelimiter = false;
                break;
            }
        }

        if (list.size() == 0) {
            return false;
        }

        // Construct canonical ID
        for (int i=0; i<list.size(); ++i) {
            SingleID single = list.get(i);
            canonID.append(single.canonID);
            if (i != (list.size()-1)) {
                canonID.append(ID_DELIM);
            }
        }

        // Parse trailing global filter, if any, and only if we saw
        // a trailing delimiter after the IDs.
        if (sawDelimiter) {
            withParens[0] = 1; // parens required
            filter = parseGlobalFilter(id, pos, dir, withParens, canonID);
            if (filter != null) {
                // Don't require trailing ';', but parse it if present
                Utility.parseChar(id, pos, ID_DELIM);
                
                if (dir == REVERSE) {
                    globalFilter[0] = filter;
                }
            }
        }

        // Trailing unparsed text is a syntax error
        pos[0] = PatternProps.skipWhiteSpace(id, pos[0]);
        if (pos[0] != id.length()) {
            return false;
        }

        return true;
    }

    /**
     * Returns the list of Transliterator objects for the
     * given list of SingleID objects.
     * 
     * @param ids list vector of SingleID objects.
     * @return Actual transliterators for the list of SingleIDs
     */
    static List<Transliterator> instantiateList(List<SingleID> ids) {
        Transliterator t;
        List<Transliterator> translits = new ArrayList<Transliterator>();
        for (SingleID single : ids) {
            if (single.basicID.length() == 0) {
                continue;
            }
            t = single.getInstance();
            if (t == null) {
                throw new IllegalArgumentException("Illegal ID " + single.canonID);
            }
            translits.add(t);
        }

        // An empty list is equivalent to a Null transliterator.
        if (translits.size() == 0) {
            t = Transliterator.getBasicInstance("Any-Null", null);
            if (t == null) {
                // Should never happen
                throw new IllegalArgumentException("Internal error; cannot instantiate Any-Null");
            }
            translits.add(t);
        }
        return translits;
    }

    /**
     * Parse an ID into pieces.  Take IDs of the form T, T/V, S-T,
     * S-T/V, or S/V-T.  If the source is missing, return a source of
     * ANY.
     * @param id the id string, in any of several forms
     * @return an array of 4 strings: source, target, variant, and
     * isSourcePresent.  If the source is not present, ANY will be
     * given as the source, and isSourcePresent will be null.  Otherwise
     * isSourcePresent will be non-null.  The target may be empty if the
     * id is not well-formed.  The variant may be empty.
     */
    public static String[] IDtoSTV(String id) {
        String source = ANY;
        String target = null;
        String variant = "";
        
        int sep = id.indexOf(TARGET_SEP);
        int var = id.indexOf(VARIANT_SEP);
        if (var < 0) {
            var = id.length();
        }
        boolean isSourcePresent = false;
        
        if (sep < 0) {
            // Form: T/V or T (or /V)
            target = id.substring(0, var);
            variant = id.substring(var);
        } else if (sep < var) {
            // Form: S-T/V or S-T (or -T/V or -T)
            if (sep > 0) {
                source = id.substring(0, sep);
              isSourcePresent = true;
            }
            target = id.substring(++sep, var);
            variant = id.substring(var);
        } else {
            // Form: (S/V-T or /V-T)
            if (var > 0) {
                source = id.substring(0, var);
                isSourcePresent = true;
            }
            variant = id.substring(var, sep++);
            target = id.substring(sep);
        }

        if (variant.length() > 0) {
            variant = variant.substring(1);
        }
        
        return new String[] { source, target, variant,
                              isSourcePresent ? "" : null };
    }

    /**
     * Given source, target, and variant strings, concatenate them into a
     * full ID.  If the source is empty, then "Any" will be used for the
     * source, so the ID will always be of the form s-t/v or s-t.
     */
    public static String STVtoID(String source,
                                 String target,
                                 String variant) {
        StringBuilder id = new StringBuilder(source);
        if (id.length() == 0) {
            id.append(ANY);
        }
        id.append(TARGET_SEP).append(target);
        if (variant != null && variant.length() != 0) {
            id.append(VARIANT_SEP).append(variant);
        }
        return id.toString();
    }

    /**
     * Register two targets as being inverses of one another.  For
     * example, calling registerSpecialInverse("NFC", "NFD", true) causes
     * Transliterator to form the following inverse relationships:
     *
     * <pre>NFC => NFD
     * Any-NFC => Any-NFD
     * NFD => NFC
     * Any-NFD => Any-NFC</pre>
     *
     * (Without the special inverse registration, the inverse of NFC
     * would be NFC-Any.)  Note that NFD is shorthand for Any-NFD, but
     * that the presence or absence of "Any-" is preserved.
     *
     * <p>The relationship is symmetrical; registering (a, b) is
     * equivalent to registering (b, a).
     *
     * <p>The relevant IDs must still be registered separately as
     * factories or classes.
     *
     * <p>Only the targets are specified.  Special inverses always
     * have the form Any-Target1 <=> Any-Target2.  The target should
     * have canonical casing (the casing desired to be produced when
     * an inverse is formed) and should contain no whitespace or other
     * extraneous characters.
     *
     * @param target the target against which to register the inverse
     * @param inverseTarget the inverse of target, that is
     * Any-target.getInverse() => Any-inverseTarget
     * @param bidirectional if true, register the reverse relation
     * as well, that is, Any-inverseTarget.getInverse() => Any-target
     */
    public static void registerSpecialInverse(String target,
                                              String inverseTarget,
                                              boolean bidirectional) {
        SPECIAL_INVERSES.put(new CaseInsensitiveString(target), inverseTarget);
        if (bidirectional && !target.equalsIgnoreCase(inverseTarget)) {
            SPECIAL_INVERSES.put(new CaseInsensitiveString(inverseTarget), target);
        }
    }

    //----------------------------------------------------------------
    // Private implementation
    //----------------------------------------------------------------

    /**
     * Parse an ID into component pieces.  Take IDs of the form T,
     * T/V, S-T, S-T/V, or S/V-T.  If the source is missing, return a
     * source of ANY.
     * @param id the id string, in any of several forms
     * @param pos INPUT-OUTPUT parameter.  On input, pos[0] is the
     * offset of the first character to parse in id.  On output,
     * pos[0] is the offset after the last parsed character.  If the
     * parse failed, pos[0] will be unchanged.
     * @param allowFilter if true, a UnicodeSet pattern is allowed
     * at any location between specs or delimiters, and is returned
     * as the fifth string in the array.
     * @return a Specs object, or null if the parse failed.  If
     * neither source nor target was seen in the parsed id, then the
     * parse fails.  If allowFilter is true, then the parsed filter
     * pattern is returned in the Specs object, otherwise the returned
     * filter reference is null.  If the parse fails for any reason
     * null is returned.
     */
    private static Specs parseFilterID(String id, int[] pos,
                                       boolean allowFilter) {
        String first = null;
        String source = null;
        String target = null;
        String variant = null;
        String filter = null;
        char delimiter = 0;
        int specCount = 0;
        int start = pos[0];

        // This loop parses one of the following things with each
        // pass: a filter, a delimiter character (either '-' or '/'),
        // or a spec (source, target, or variant).
        for (;;) {
            pos[0] = PatternProps.skipWhiteSpace(id, pos[0]);
            if (pos[0] == id.length()) {
                break;
            }

            // Parse filters
            if (allowFilter && filter == null &&
                UnicodeSet.resemblesPattern(id, pos[0])) {

                ParsePosition ppos = new ParsePosition(pos[0]);
                // Parse the set to get the position.
                new UnicodeSet(id, ppos, null);
                filter = id.substring(pos[0], ppos.getIndex());
                pos[0] = ppos.getIndex();
                continue;
            }

            if (delimiter == 0) {
                char c = id.charAt(pos[0]);
                if ((c == TARGET_SEP && target == null) ||
                    (c == VARIANT_SEP && variant == null)) {
                    delimiter = c;
                    ++pos[0];
                    continue;
                }
            }

            // We are about to try to parse a spec with no delimiter
            // when we can no longer do so (we can only do so at the
            // start); break.
            if (delimiter == 0 && specCount > 0) {
                break;
            }

            String spec = Utility.parseUnicodeIdentifier(id, pos);
            if (spec == null) {
                // Note that if there was a trailing delimiter, we
                // consume it.  So Foo-, Foo/, Foo-Bar/, and Foo/Bar-
                // are legal.
                break;
            }

            switch (delimiter) {
            case 0:
                first = spec;
                break;
            case TARGET_SEP:
                target = spec;
                break;
            case VARIANT_SEP:
                variant = spec;
                break;
            }
            ++specCount;
            delimiter = 0;
        }

        // A spec with no prior character is either source or target,
        // depending on whether an explicit "-target" was seen.
        if (first != null) {
            if (target == null) {
                target = first;
            } else {
                source = first;
            }
        }

        // Must have either source or target
        if (source == null && target == null) {
            pos[0] = start;
            return null;
        }

        // Empty source or target defaults to ANY
        boolean sawSource = true;
        if (source == null) {
            source = ANY;
            sawSource = false;
        }
        if (target == null) {
            target = ANY;
        }

        return new Specs(source, target, variant, sawSource, filter);
    }

    /**
     * Givens a Spec object, convert it to a SingleID object.  The
     * Spec object is a more unprocessed parse result.  The SingleID
     * object contains information about canonical and basic IDs.
     * @return a SingleID; never returns null.  Returned object always
     * has 'filter' field of null.
     */
    private static SingleID specsToID(Specs specs, int dir) {
        String canonID = "";
        String basicID = "";
        String basicPrefix = "";
        if (specs != null) {
            StringBuilder buf = new StringBuilder();
            if (dir == FORWARD) {
                if (specs.sawSource) {
                    buf.append(specs.source).append(TARGET_SEP);
                } else {
                    basicPrefix = specs.source + TARGET_SEP;
                }
                buf.append(specs.target);
            } else {
                buf.append(specs.target).append(TARGET_SEP).append(specs.source);
            }
            if (specs.variant != null) {
                buf.append(VARIANT_SEP).append(specs.variant);
            }
            basicID = basicPrefix + buf.toString();
            if (specs.filter != null) {
                buf.insert(0, specs.filter);
            }
            canonID = buf.toString();
        }
        return new SingleID(canonID, basicID);
    }

    /**
     * Given a Specs object, return a SingleID representing the
     * special inverse of that ID.  If there is no special inverse
     * then return null.
     * @return a SingleID or null.  Returned object always has
     * 'filter' field of null.
     */
    private static SingleID specsToSpecialInverse(Specs specs) {
        if (!specs.source.equalsIgnoreCase(ANY)) {
            return null;
        }
        String inverseTarget = SPECIAL_INVERSES.get(new CaseInsensitiveString(specs.target));
        if (inverseTarget != null) {
            // If the original ID contained "Any-" then make the
            // special inverse "Any-Foo"; otherwise make it "Foo".
            // So "Any-NFC" => "Any-NFD" but "NFC" => "NFD".
            StringBuilder buf = new StringBuilder();
            if (specs.filter != null) {
                buf.append(specs.filter);
            }
            if (specs.sawSource) {
                buf.append(ANY).append(TARGET_SEP);
            }
            buf.append(inverseTarget);

            String basicID = ANY + TARGET_SEP + inverseTarget;

            if (specs.variant != null) {
                buf.append(VARIANT_SEP).append(specs.variant);
                basicID = basicID + VARIANT_SEP + specs.variant;
            }
            return new SingleID(buf.toString(), basicID);
        }
        return null;
    }
}

//eof
