// Copyright (C) 2006 Google Inc.
//
// Licensed 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 prettify;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CombinePrefixPattern {

    protected int capturedGroupIndex = 0;
    protected boolean needToFoldCase = false;

    public CombinePrefixPattern() {
    }

    /**
     * Given a group of {@link java.util.regex.Pattern}s, returns a {@code RegExp} that globally
     * matches the union of the sets of strings matched by the input RegExp.
     * Since it matches globally, if the input strings have a start-of-input
     * anchor (/^.../), it is ignored for the purposes of unioning.
     * @param regexs non multiline, non-global regexs.
     * @return Pattern a global regex.
     */
    public Pattern combinePrefixPattern(List<Pattern> regexs) throws Exception {
        boolean ignoreCase = false;

        for (int i = 0, n = regexs.size(); i < n; ++i) {
            Pattern regex = regexs.get(i);
            if ((regex.flags() & Pattern.CASE_INSENSITIVE) != 0) {
                ignoreCase = true;
            } else if (Util.test(Pattern.compile("[a-z]", Pattern.CASE_INSENSITIVE), regex.pattern().replaceAll("\\\\[Uu][0-9A-Fa-f]{4}|\\\\[Xx][0-9A-Fa-f]{2}|\\\\[^UuXx]", ""))) {
                needToFoldCase = true;
                ignoreCase = false;
                break;
            }
        }

        List<String> rewritten = new ArrayList<String>();
        for (int i = 0, n = regexs.size(); i < n; ++i) {
            Pattern regex = regexs.get(i);
            if ((regex.flags() & Pattern.MULTILINE) != 0) {
                throw new Exception(regex.pattern());
            }
            rewritten.add("(?:" + allowAnywhereFoldCaseAndRenumberGroups(regex) + ")");
        }

        return ignoreCase ? Pattern.compile(Util.join(rewritten, "|"), Pattern.CASE_INSENSITIVE) : Pattern.compile(Util.join(rewritten, "|"));
    }
    protected static final Map<Character, Integer> escapeCharToCodeUnit = new HashMap<Character, Integer>();

    static {
        escapeCharToCodeUnit.put('b', 8);
        escapeCharToCodeUnit.put('t', 9);
        escapeCharToCodeUnit.put('n', 0xa);
        escapeCharToCodeUnit.put('v', 0xb);
        escapeCharToCodeUnit.put('f', 0xc);
        escapeCharToCodeUnit.put('r', 0xf);
    }

    protected static int decodeEscape(String charsetPart) {
        Integer cc0 = charsetPart.codePointAt(0);
        if (cc0 != 92 /* \\ */) {
            return cc0;
        }
        char c1 = charsetPart.charAt(1);
        cc0 = escapeCharToCodeUnit.get(c1);
        if (cc0 != null) {
            return cc0;
        } else if ('0' <= c1 && c1 <= '7') {
            return Integer.parseInt(charsetPart.substring(1), 8);
        } else if (c1 == 'u' || c1 == 'x') {
            return Integer.parseInt(charsetPart.substring(2), 16);
        } else {
            return charsetPart.codePointAt(1);
        }
    }

    protected static String encodeEscape(int charCode) {
        if (charCode < 0x20) {
            return (charCode < 0x10 ? "\\x0" : "\\x") + Integer.toString(charCode, 16);
        }

        String ch = new String(Character.toChars(charCode));
        return (charCode == '\\' || charCode == '-' || charCode == ']' || charCode == '^')
                ? "\\" + ch : ch;
    }

    protected static String caseFoldCharset(String charSet) {
        String[] charsetParts = Util.match(Pattern.compile("\\\\u[0-9A-Fa-f]{4}"
                + "|\\\\x[0-9A-Fa-f]{2}"
                + "|\\\\[0-3][0-7]{0,2}"
                + "|\\\\[0-7]{1,2}"
                + "|\\\\[\\s\\S]"
                + "|-"
                + "|[^-\\\\]"), charSet.substring(1, charSet.length() - 1));
        List<List<Integer>> ranges = new ArrayList<List<Integer>>();
        boolean inverse = charsetParts[0] != null && charsetParts[0].equals("^");

        List<String> out = new ArrayList<String>(Arrays.asList(new String[]{"["}));
        if (inverse) {
            out.add("^");
        }

        for (int i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
            String p = charsetParts[i];
            if (Util.test(Pattern.compile("\\\\[bdsw]", Pattern.CASE_INSENSITIVE), p)) {  // Don't muck with named groups.
                out.add(p);
            } else {
                int start = decodeEscape(p);
                int end;
                if (i + 2 < n && "-".equals(charsetParts[i + 1])) {
                    end = decodeEscape(charsetParts[i + 2]);
                    i += 2;
                } else {
                    end = start;
                }
                ranges.add(Arrays.asList(new Integer[]{start, end}));
                // If the range might intersect letters, then expand it.
                // This case handling is too simplistic.
                // It does not deal with non-latin case folding.
                // It works for latin source code identifiers though.
                if (!(end < 65 || start > 122)) {
                    if (!(end < 65 || start > 90)) {
                        ranges.add(Arrays.asList(new Integer[]{Math.max(65, start) | 32, Math.min(end, 90) | 32}));
                    }
                    if (!(end < 97 || start > 122)) {
                        ranges.add(Arrays.asList(new Integer[]{Math.max(97, start) & ~32, Math.min(end, 122) & ~32}));
                    }
                }
            }
        }

        // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
        // -> [[1, 12], [14, 14], [16, 17]]
        Collections.sort(ranges, new Comparator<List<Integer>>() {

            @Override
            public int compare(List<Integer> a, List<Integer> b) {
                return a.get(0) != b.get(0) ? (a.get(0) - b.get(0)) : (b.get(1) - a.get(1));
            }
        });
        List<List<Integer>> consolidatedRanges = new ArrayList<List<Integer>>();
//        List<Integer> lastRange = Arrays.asList(new Integer[]{0, 0});
        List<Integer> lastRange = new ArrayList<Integer>(Arrays.asList(new Integer[]{0, 0}));
        for (int i = 0; i < ranges.size(); ++i) {
            List<Integer> range = ranges.get(i);
            if (lastRange.get(1) != null && range.get(0) <= lastRange.get(1) + 1) {
                lastRange.set(1, Math.max(lastRange.get(1), range.get(1)));
            } else {
                // reference of lastRange is added
                consolidatedRanges.add(lastRange = range);
            }
        }

        for (int i = 0; i < consolidatedRanges.size(); ++i) {
            List<Integer> range = consolidatedRanges.get(i);
            out.add(encodeEscape(range.get(0)));
            if (range.get(1) > range.get(0)) {
                if (range.get(1) + 1 > range.get(0)) {
                    out.add("-");
                }
                out.add(encodeEscape(range.get(1)));
            }
        }
        out.add("]");

        return Util.join(out);
    }

    protected String allowAnywhereFoldCaseAndRenumberGroups(Pattern regex) {
        // Split into character sets, escape sequences, punctuation strings
        // like ('(', '(?:', ')', '^'), and runs of characters that do not
        // include any of the above.
        String[] parts = Util.match(Pattern.compile("(?:"
                + "\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]" // a character set
                + "|\\\\u[A-Fa-f0-9]{4}" // a unicode escape
                + "|\\\\x[A-Fa-f0-9]{2}" // a hex escape
                + "|\\\\[0-9]+" // a back-reference or octal escape
                + "|\\\\[^ux0-9]" // other escape sequence
                + "|\\(\\?[:!=]" // start of a non-capturing group
                + "|[\\(\\)\\^]" // start/end of a group, or line start
                + "|[^\\x5B\\x5C\\(\\)\\^]+" // run of other characters
                + ")"), regex.pattern());
        int n = parts.length;

        // Maps captured group numbers to the number they will occupy in
        // the output or to -1 if that has not been determined, or to
        // undefined if they need not be capturing in the output.
        Map<Integer, Integer> capturedGroups = new HashMap<Integer, Integer>();

        // Walk over and identify back references to build the capturedGroups
        // mapping.
        for (int i = 0, groupIndex = 0; i < n; ++i) {
            String p = parts[i];
            if (p.equals("(")) {
                // groups are 1-indexed, so max group index is count of '('
                ++groupIndex;
            } else if ('\\' == p.charAt(0)) {
                try {
                    int decimalValue = Math.abs(Integer.parseInt(p.substring(1)));
                    if (decimalValue <= groupIndex) {
                        capturedGroups.put(decimalValue, -1);
                    } else {
                        // Replace with an unambiguous escape sequence so that
                        // an octal escape sequence does not turn into a backreference
                        // to a capturing group from an earlier regex.
                        parts[i] = encodeEscape(decimalValue);
                    }
                } catch (NumberFormatException ex) {
                }
            }
        }

        // Renumber groups and reduce capturing groups to non-capturing groups
        // where possible.
        for (int i : capturedGroups.keySet()) {
            if (-1 == capturedGroups.get(i)) {
                capturedGroups.put(i, ++capturedGroupIndex);
            }
        }
        for (int i = 0, groupIndex = 0; i < n; ++i) {
            String p = parts[i];
            if (p.equals("(")) {
                ++groupIndex;
                if (capturedGroups.get(groupIndex) == null) {
                    parts[i] = "(?:";
                }
            } else if ('\\' == p.charAt(0)) {
                try {
                    int decimalValue = Math.abs(Integer.parseInt(p.substring(1)));
                    if (decimalValue <= groupIndex) {
                        parts[i] = "\\" + capturedGroups.get(decimalValue);
                    }
                } catch (NumberFormatException ex) {
                }
            }
        }

        // Remove any prefix anchors so that the output will match anywhere.
        // ^^ really does mean an anchored match though.
        for (int i = 0; i < n; ++i) {
            if ("^".equals(parts[i]) && !"^".equals(parts[i + 1])) {
                parts[i] = "";
            }
        }

        // Expand letters to groups to handle mixing of case-sensitive and
        // case-insensitive patterns if necessary.
        if ((regex.flags() & Pattern.CASE_INSENSITIVE) != 0 && needToFoldCase) {
            for (int i = 0; i < n; ++i) {
                String p = parts[i];
                char ch0 = p.length() > 0 ? p.charAt(0) : 0;
                if (p.length() >= 2 && ch0 == '[') {
                    parts[i] = caseFoldCharset(p);
                } else if (ch0 != '\\') {
                    // TODO: handle letters in numeric escapes.
                    StringBuffer sb = new StringBuffer();
                    Matcher _matcher = Pattern.compile("[a-zA-Z]").matcher(p);
                    while (_matcher.find()) {
                        int cc = _matcher.group(0).codePointAt(0);
                        _matcher.appendReplacement(sb, "");
                        sb.append("[").append(Character.toString((char) (cc & ~32))).append(Character.toString((char) (cc | 32))).append("]");
                    }
                    _matcher.appendTail(sb);
                    parts[i] = sb.toString();
                }
            }
        }

        return Util.join(parts);
    }
}
