/*   Copyright 2004 The Apache Software Foundation
 *
 *   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 org.apache.xmlbeans.impl.regex;

/**
 * This class represents a character class such as [a-z] or a period.
 */
final class RangeToken extends Token implements java.io.Serializable {

    int[] ranges;
    boolean sorted;
    boolean compacted;
    RangeToken icaseCache = null;
    int[] map = null;
    int nonMapIndex;

    RangeToken(int type) {
        super(type);
        this.setSorted(false);
    }

    // for RANGE or NRANGE
    protected void addRange(int start, int end) {
        this.icaseCache = null;
        //System.err.println("Token#addRange(): "+start+" "+end);
        int r1, r2;
        if (start <= end) {
            r1 = start;
            r2 = end;
        } else {
            r1 = end;
            r2 = start;
        }

        if (this.ranges == null) {
            this.ranges = new int[2];
            this.ranges[0] = r1;
            this.ranges[1] = r2;
            this.setSorted(true);
        } else {
            int pos = this.ranges.length;
            if (this.ranges[pos - 1] + 1 == r1) {
                this.ranges[pos - 1] = r2;
                return;
            }
            int[] temp = new int[pos + 2];
            System.arraycopy(this.ranges, 0, temp, 0, pos);
            this.ranges = temp;
            if (this.ranges[pos - 1] >= r1) {
                this.setSorted(false);
            }
            this.ranges[pos++] = r1;
            this.ranges[pos] = r2;
            if (!this.sorted) {
                this.sortRanges();
            }
        }
    }

    private boolean isSorted() {
        return this.sorted;
    }

    private void setSorted(boolean sort) {
        this.sorted = sort;
        if (!sort) {
            this.compacted = false;
        }
    }

    private boolean isCompacted() {
        return this.compacted;
    }

    private void setCompacted() {
        this.compacted = true;
    }

    protected void sortRanges() {
        if (this.isSorted()) {
            return;
        }
        if (this.ranges == null) {
            return;
        }
        //System.err.println("Do sorting: "+this.ranges.length);

        // Bubble sort
        // Why? -- In many cases,
        //         this.ranges has few elements.
        for (int i = this.ranges.length - 4; i >= 0; i -= 2) {
            for (int j = 0; j <= i; j += 2) {
                if (this.ranges[j] > this.ranges[j + 2]
                    || this.ranges[j] == this.ranges[j + 2] && this.ranges[j + 1] > this.ranges[j + 3]) {
                    int tmp;
                    tmp = this.ranges[j + 2];
                    this.ranges[j + 2] = this.ranges[j];
                    this.ranges[j] = tmp;
                    tmp = this.ranges[j + 3];
                    this.ranges[j + 3] = this.ranges[j + 1];
                    this.ranges[j + 1] = tmp;
                }
            }
        }
        this.setSorted(true);
    }

    /**
     * this.ranges is sorted.
     */
    @SuppressWarnings("ConstantConditions")
    protected void compactRanges() {
        boolean DEBUG = false;
        if (this.ranges == null || this.ranges.length <= 2) {
            return;
        }
        if (this.isCompacted()) {
            return;
        }
        int base = 0;                           // Index of writing point
        int target = 0;                         // Index of processing point

        while (target < this.ranges.length) {
            if (base != target) {
                this.ranges[base] = this.ranges[target++];
                this.ranges[base + 1] = this.ranges[target++];
            } else {
                target += 2;
            }
            int baseend = this.ranges[base + 1];
            while (target < this.ranges.length) {
                if (baseend + 1 < this.ranges[target]) {
                    break;
                }
                if (baseend + 1 == this.ranges[target]) {
                    if (DEBUG) {
                        System.err.println("Token#compactRanges(): Compaction: [" + this.ranges[base]
                                           + ", " + this.ranges[base + 1]
                                           + "], [" + this.ranges[target]
                                           + ", " + this.ranges[target + 1]
                                           + "] -> [" + this.ranges[base]
                                           + ", " + this.ranges[target + 1]
                                           + "]");
                    }
                    this.ranges[base + 1] = this.ranges[target + 1];
                    baseend = this.ranges[base + 1];
                    target += 2;
                } else if (baseend >= this.ranges[target + 1]) {
                    if (DEBUG) {
                        System.err.println("Token#compactRanges(): Compaction: [" + this.ranges[base]
                                           + ", " + this.ranges[base + 1]
                                           + "], [" + this.ranges[target]
                                           + ", " + this.ranges[target + 1]
                                           + "] -> [" + this.ranges[base]
                                           + ", " + this.ranges[base + 1]
                                           + "]");
                    }
                    target += 2;
                } else if (baseend < this.ranges[target + 1]) {
                    if (DEBUG) {
                        System.err.println("Token#compactRanges(): Compaction: [" + this.ranges[base]
                                           + ", " + this.ranges[base + 1]
                                           + "], [" + this.ranges[target]
                                           + ", " + this.ranges[target + 1]
                                           + "] -> [" + this.ranges[base]
                                           + ", " + this.ranges[target + 1]
                                           + "]");
                    }
                    this.ranges[base + 1] = this.ranges[target + 1];
                    baseend = this.ranges[base + 1];
                    target += 2;
                } else {
                    throw new RuntimeException("Token#compactRanges(): Internel Error: ["
                                               + this.ranges[base]
                                               + "," + this.ranges[base + 1]
                                               + "] [" + this.ranges[target]
                                               + "," + this.ranges[target + 1] + "]");
                }
            } // while
            base += 2;
        }

        if (base != this.ranges.length) {
            int[] result = new int[base];
            System.arraycopy(this.ranges, 0, result, 0, base);
            this.ranges = result;
        }
        this.setCompacted();
    }

    protected void mergeRanges(Token token) {
        RangeToken tok = (RangeToken) token;
        this.sortRanges();
        tok.sortRanges();
        if (tok.ranges == null) {
            return;
        }
        this.icaseCache = null;
        this.setSorted(true);
        if (this.ranges == null) {
            this.ranges = new int[tok.ranges.length];
            System.arraycopy(tok.ranges, 0, this.ranges, 0, tok.ranges.length);
            return;
        }
        int[] result = new int[this.ranges.length + tok.ranges.length];
        for (int i = 0, j = 0, k = 0; i < this.ranges.length || j < tok.ranges.length; ) {
            if (i >= this.ranges.length) {
                result[k++] = tok.ranges[j++];
                result[k++] = tok.ranges[j++];
            } else if (j >= tok.ranges.length) {
                result[k++] = this.ranges[i++];
                result[k++] = this.ranges[i++];
            } else if (tok.ranges[j] < this.ranges[i]
                       || tok.ranges[j] == this.ranges[i] && tok.ranges[j + 1] < this.ranges[i + 1]) {
                result[k++] = tok.ranges[j++];
                result[k++] = tok.ranges[j++];
            } else {
                result[k++] = this.ranges[i++];
                result[k++] = this.ranges[i++];
            }
        }
        this.ranges = result;
    }

    protected void subtractRanges(Token token) {
        if (token.type == NRANGE) {
            this.intersectRanges(token);
            return;
        }
        RangeToken tok = (RangeToken) token;
        if (tok.ranges == null || this.ranges == null) {
            return;
        }
        this.icaseCache = null;
        this.sortRanges();
        this.compactRanges();
        tok.sortRanges();
        tok.compactRanges();

        //System.err.println("Token#substractRanges(): Entry: "+this.ranges.length+", "+tok.ranges.length);

        int[] result = new int[this.ranges.length + tok.ranges.length];
        int wp = 0, src = 0, sub = 0;
        while (src < this.ranges.length && sub < tok.ranges.length) {
            int srcbegin = this.ranges[src];
            int srcend = this.ranges[src + 1];
            int subbegin = tok.ranges[sub];
            int subend = tok.ranges[sub + 1];
            if (srcend < subbegin) {            // Not overlapped
                // src: o-----o
                // sub:         o-----o
                // res: o-----o
                // Reuse sub
                result[wp++] = this.ranges[src++];
                result[wp++] = this.ranges[src++];
            } else if (srcend >= subbegin
                       && srcbegin <= subend) { // Overlapped
                // src:    o--------o
                // sub:  o----o
                // sub:      o----o
                // sub:          o----o
                // sub:  o------------o
                if (subbegin <= srcbegin && srcend <= subend) {
                    // src:    o--------o
                    // sub:  o------------o
                    // res: empty
                    // Reuse sub
                    src += 2;
                } else if (subbegin <= srcbegin) {
                    // src:    o--------o
                    // sub:  o----o
                    // res:       o-----o
                    // Reuse src(=res)
                    this.ranges[src] = subend + 1;
                    sub += 2;
                } else if (srcend <= subend) {
                    // src:    o--------o
                    // sub:          o----o
                    // res:    o-----o
                    // Reuse sub
                    result[wp++] = srcbegin;
                    result[wp++] = subbegin - 1;
                    src += 2;
                } else {
                    // src:    o--------o
                    // sub:      o----o
                    // res:    o-o    o-o
                    // Reuse src(=right res)
                    result[wp++] = srcbegin;
                    result[wp++] = subbegin - 1;
                    this.ranges[src] = subend + 1;
                    sub += 2;
                }
            } else if (subend < srcbegin) {
                // Not overlapped
                // src:          o-----o
                // sub: o----o
                sub += 2;
            } else {
                throw new RuntimeException("Token#subtractRanges(): Internal Error: [" + this.ranges[src]
                                           + "," + this.ranges[src + 1]
                                           + "] - [" + tok.ranges[sub]
                                           + "," + tok.ranges[sub + 1]
                                           + "]");
            }
        }
        while (src < this.ranges.length) {
            result[wp++] = this.ranges[src++];
            result[wp++] = this.ranges[src++];
        }
        this.ranges = new int[wp];
        System.arraycopy(result, 0, this.ranges, 0, wp);
        // this.ranges is sorted and compacted.
    }

    /**
     * @param token Ignore whether it is NRANGE or not.
     */
    protected void intersectRanges(Token token) {
        RangeToken tok = (RangeToken) token;
        if (tok.ranges == null || this.ranges == null) {
            return;
        }
        this.icaseCache = null;
        this.sortRanges();
        this.compactRanges();
        tok.sortRanges();
        tok.compactRanges();

        int[] result = new int[this.ranges.length + tok.ranges.length];
        int wp = 0, src1 = 0, src2 = 0;
        while (src1 < this.ranges.length && src2 < tok.ranges.length) {
            int src1begin = this.ranges[src1];
            int src1end = this.ranges[src1 + 1];
            int src2begin = tok.ranges[src2];
            int src2end = tok.ranges[src2 + 1];
            if (src1end < src2begin) {          // Not overlapped
                // src1: o-----o
                // src2:         o-----o
                // res:  empty
                // Reuse src2
                src1 += 2;
            } else if (src1end >= src2begin
                       && src1begin <= src2end) { // Overlapped
                // src1:    o--------o
                // src2:  o----o
                // src2:      o----o
                // src2:          o----o
                // src2:  o------------o
                if (src2begin <= src1begin && src1end <= src2end) {
                    // src1:    o--------o
                    // src2:  o------------o
                    // res:     o--------o
                    // Reuse src2
                    result[wp++] = src1begin;
                    result[wp++] = src1end;
                    src1 += 2;
                } else if (src2begin <= src1begin) {
                    // src1:    o--------o
                    // src2:  o----o
                    // res:     o--o
                    // Reuse the rest of src1
                    result[wp++] = src1begin;
                    result[wp++] = src2end;
                    this.ranges[src1] = src2end + 1;
                    src2 += 2;
                } else if (src1end <= src2end) {
                    // src1:    o--------o
                    // src2:          o----o
                    // res:           o--o
                    // Reuse src2
                    result[wp++] = src2begin;
                    result[wp++] = src1end;
                    src1 += 2;
                } else {
                    // src1:    o--------o
                    // src2:      o----o
                    // res:       o----o
                    // Reuse the rest of src1
                    result[wp++] = src2begin;
                    result[wp++] = src2end;
                    this.ranges[src1] = src2end + 1;
                }
            } else if (src2end < src1begin) {
                // Not overlapped
                // src1:          o-----o
                // src2: o----o
                src2 += 2;
            } else {
                throw new RuntimeException("Token#intersectRanges(): Internal Error: ["
                                           + this.ranges[src1]
                                           + "," + this.ranges[src1 + 1]
                                           + "] & [" + tok.ranges[src2]
                                           + "," + tok.ranges[src2 + 1]
                                           + "]");
            }
        }
        while (src1 < this.ranges.length) {
            result[wp++] = this.ranges[src1++];
            result[wp++] = this.ranges[src1++];
        }
        this.ranges = new int[wp];
        System.arraycopy(result, 0, this.ranges, 0, wp);
        // this.ranges is sorted and compacted.
    }

    /**
     * for RANGE: Creates complement.
     * for NRANGE: Creates the same meaning RANGE.
     */
    static Token complementRanges(Token token) {
        if (token.type != RANGE && token.type != NRANGE) {
            throw new IllegalArgumentException("Token#complementRanges(): must be RANGE: " + token.type);
        }
        RangeToken tok = (RangeToken) token;
        tok.sortRanges();
        tok.compactRanges();
        int len = tok.ranges.length + 2;
        if (tok.ranges[0] == 0) {
            len -= 2;
        }
        int last = tok.ranges[tok.ranges.length - 1];
        if (last == UTF16_MAX) {
            len -= 2;
        }
        RangeToken ret = Token.createRange();
        ret.ranges = new int[len];
        int wp = 0;
        if (tok.ranges[0] > 0) {
            ret.ranges[wp++] = 0;
            ret.ranges[wp++] = tok.ranges[0] - 1;
        }
        for (int i = 1; i < tok.ranges.length - 2; i += 2) {
            ret.ranges[wp++] = tok.ranges[i] + 1;
            ret.ranges[wp++] = tok.ranges[i + 1] - 1;
        }
        if (last != UTF16_MAX) {
            ret.ranges[wp++] = last + 1;
            ret.ranges[wp] = UTF16_MAX;
        }
        ret.setCompacted();
        return ret;
    }

    synchronized RangeToken getCaseInsensitiveToken() {
        if (this.icaseCache != null) {
            return this.icaseCache;
        }

        RangeToken uppers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
        for (int i = 0; i < this.ranges.length; i += 2) {
            for (int ch = this.ranges[i]; ch <= this.ranges[i + 1]; ch++) {
                if (ch > 0xffff) {
                    uppers.addRange(ch, ch);
                } else {
                    char uch = Character.toUpperCase((char) ch);
                    uppers.addRange(uch, uch);
                }
            }
        }
        RangeToken lowers = this.type == Token.RANGE ? Token.createRange() : Token.createNRange();
        for (int i = 0; i < uppers.ranges.length; i += 2) {
            for (int ch = uppers.ranges[i]; ch <= uppers.ranges[i + 1]; ch++) {
                if (ch > 0xffff) {
                    lowers.addRange(ch, ch);
                } else {
                    char uch = Character.toUpperCase((char) ch);
                    lowers.addRange(uch, uch);
                }
            }
        }
        lowers.mergeRanges(uppers);
        lowers.mergeRanges(this);
        lowers.compactRanges();

        this.icaseCache = lowers;
        return lowers;
    }

    boolean match(int ch) {
        if (this.map == null) {
            this.createMap();
        }
        boolean ret;
        if (this.type == RANGE) {
            if (ch < MAPSIZE) {
                return (this.map[ch / 32] & (1 << (ch & 0x1f))) != 0;
            }
            ret = false;
            for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) {
                if (this.ranges[i] <= ch && ch <= this.ranges[i + 1]) {
                    return true;
                }
            }
        } else {
            if (ch < MAPSIZE) {
                return (this.map[ch / 32] & (1 << (ch & 0x1f))) == 0;
            }
            ret = true;
            for (int i = this.nonMapIndex; i < this.ranges.length; i += 2) {
                if (this.ranges[i] <= ch && ch <= this.ranges[i + 1]) {
                    return false;
                }
            }
        }
        return ret;
    }

    private static final int MAPSIZE = 256;

    private void createMap() {
        int asize = MAPSIZE / 32;                 // 32 is the number of bits in `int'.
        // CHANGE(radup) we need a new map, since this is not synchronized
        // and if we init the instance map with 0's it's going to be trouble
        // -this.map = new int[asize];
        // -this.nonMapIndex = this.ranges.length;
        // -for (int i = 0; i < asize; i++) this.map[i] = 0;
        int[] localmap = new int[asize]; // +
        int localnonMapIndex = this.ranges.length; // +
        for (int i = 0; i < asize; i++) {
            localmap[i] = 0; // + redundant
        }
        for (int i = 0; i < this.ranges.length; i += 2) {
            int s = this.ranges[i];
            int e = this.ranges[i + 1];
            if (s < MAPSIZE) {
                for (int j = s; j <= e && j < MAPSIZE; j++) {
                    localmap[j / 32] |= 1 << (j & 0x1f); // s&0x1f : 0-31
                }
            } else {
                localnonMapIndex = i;
                break;
            }
            if (e >= MAPSIZE) {
                localnonMapIndex = i;
                break;
            }
        }
        this.nonMapIndex = localnonMapIndex; // +
        this.map = localmap; // +
        //for (int i = 0;  i < asize;  i ++)  System.err.println("Map: "+Integer.toString(this.map[i], 16));
    }

    public String toString(int options) {
        String ret;
        if (this.type == RANGE) {
            if (this == Token.token_dot) {
                ret = ".";
            } else if (this == Token.token_0to9) {
                ret = "\\d";
            } else if (this == Token.token_wordchars) {
                ret = "\\w";
            } else if (this == Token.token_spaces) {
                ret = "\\s";
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append("[");
                for (int i = 0; i < this.ranges.length; i += 2) {
                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) {
                        sb.append(",");
                    }
                    if (this.ranges[i] == this.ranges[i + 1]) {
                        sb.append(escapeCharInCharClass(this.ranges[i]));
                    } else {
                        sb.append(escapeCharInCharClass(this.ranges[i]));
                        sb.append('-');
                        sb.append(escapeCharInCharClass(this.ranges[i + 1]));
                    }
                }
                sb.append("]");
                ret = sb.toString();
            }
        } else {
            if (this == Token.token_not_0to9) {
                ret = "\\D";
            } else if (this == Token.token_not_wordchars) {
                ret = "\\W";
            } else if (this == Token.token_not_spaces) {
                ret = "\\S";
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append("[^");
                for (int i = 0; i < this.ranges.length; i += 2) {
                    if ((options & RegularExpression.SPECIAL_COMMA) != 0 && i > 0) {
                        sb.append(",");
                    }
                    if (this.ranges[i] == this.ranges[i + 1]) {
                        sb.append(escapeCharInCharClass(this.ranges[i]));
                    } else {
                        sb.append(escapeCharInCharClass(this.ranges[i]));
                        sb.append('-');
                        sb.append(escapeCharInCharClass(this.ranges[i + 1]));
                    }
                }
                sb.append("]");
                ret = sb.toString();
            }
        }
        return ret;
    }

    private static String escapeCharInCharClass(int ch) {
        String ret;
        switch (ch) {
            case '[':
            case ']':
            case '-':
            case '^':
            case ',':
            case '\\':
                ret = "\\" + (char) ch;
                break;
            case '\f':
                ret = "\\f";
                break;
            case '\n':
                ret = "\\n";
                break;
            case '\r':
                ret = "\\r";
                break;
            case '\t':
                ret = "\\t";
                break;
            case 0x1b:
                ret = "\\e";
                break;
            //case 0x0b:  ret = "\\v";  break;
            default:
                if (ch < 0x20) {
                    String pre = "0" + Integer.toHexString(ch);
                    ret = "\\x" + pre.substring(pre.length() - 2);
                } else if (ch >= 0x10000) {
                    String pre = "0" + Integer.toHexString(ch);
                    ret = "\\v" + pre.substring(pre.length() - 6);
                } else {
                    ret = "" + (char) ch;
                }
        }
        return ret;
    }

}
