// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2014-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.text.CharacterIterator;
import java.util.HashSet;

import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.FilteredBreakIteratorBuilder;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.util.BytesTrie;
import com.ibm.icu.util.CharsTrie;
import com.ibm.icu.util.CharsTrieBuilder;
import com.ibm.icu.util.StringTrieBuilder;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/**
 * @author tomzhang
 */
public class SimpleFilteredSentenceBreakIterator extends BreakIterator {

    private BreakIterator delegate;
    private UCharacterIterator text; // TODO(Tom): suffice to move into the local scope in next() ?
    private CharsTrie backwardsTrie; // i.e. ".srM" for Mrs.
    private CharsTrie forwardsPartialTrie; // Has ".a" for "a.M."

    /**
     * @param adoptBreakIterator
     *            break iterator to adopt
     * @param forwardsPartialTrie
     *            forward & partial char trie to adopt
     * @param backwardsTrie
     *            backward trie to adopt
     */
    public SimpleFilteredSentenceBreakIterator(BreakIterator adoptBreakIterator, CharsTrie forwardsPartialTrie,
            CharsTrie backwardsTrie) {
        this.delegate = adoptBreakIterator;
        this.forwardsPartialTrie = forwardsPartialTrie;
        this.backwardsTrie = backwardsTrie;
    }

    @Override
    public int next() {
        int n = delegate.next();
        if (n == BreakIterator.DONE || // at end or
                backwardsTrie == null) { // .. no backwards table loaded == no exceptions
            return n;
        }
        // UCharacterIterator text;
        text = UCharacterIterator.getInstance((CharacterIterator) delegate.getText().clone());
        do { // outer loop runs once per underlying break (from fDelegate).
             // loops while 'n' points to an exception.
            text.setIndex(n);
            backwardsTrie.reset();
            int uch;

            // Assume a space is following the '.' (so we handle the case: "Mr. /Brown")
            if ((uch = text.previousCodePoint()) == ' ') { // TODO: skip a class of chars here??
                // TODO only do this the 1st time?
            } else {
                uch = text.nextCodePoint();
            }

            BytesTrie.Result r = BytesTrie.Result.INTERMEDIATE_VALUE;

            int bestPosn = -1;
            int bestValue = -1;

            while ((uch = text.previousCodePoint()) != BreakIterator.DONE && // more to consume backwards and..
                    ((r = backwardsTrie.nextForCodePoint(uch)).hasNext())) {// more in the trie
                if (r.hasValue()) { // remember the best match so far
                    bestPosn = text.getIndex();
                    bestValue = backwardsTrie.getValue();
                }
            }

            if (r.matches()) { // exact match?
                bestValue = backwardsTrie.getValue();
                bestPosn = text.getIndex();
            }

            if (bestPosn >= 0) {
                if (bestValue == Builder.MATCH) { // exact match!
                    n = delegate.next(); // skip this one. Find the next lowerlevel break.
                    if (n == BreakIterator.DONE)
                        return n;
                    continue; // See if the next is another exception.
                } else if (bestValue == Builder.PARTIAL && forwardsPartialTrie != null) {
                    // make sure there's a forward trie
                    // We matched the "Ph." in "Ph.D." - now we need to run everything through the forwards trie
                    // to see if it matches something going forward.
                    forwardsPartialTrie.reset();

                    BytesTrie.Result rfwd = BytesTrie.Result.INTERMEDIATE_VALUE;
                    text.setIndex(bestPosn); // hope that's close ..
                    while ((uch = text.nextCodePoint()) != BreakIterator.DONE
                            && ((rfwd = forwardsPartialTrie.nextForCodePoint(uch)).hasNext())) {
                    }
                    if (rfwd.matches()) {
                        // only full matches here, nothing to check
                        // skip the next:
                        n = delegate.next();
                        if (n == BreakIterator.DONE)
                            return n;
                        continue;
                    } else {
                        // no match (no exception) -return the 'underlying' break
                        return n;
                    }
                } else {
                    return n; // internal error and/or no forwards trie
                }
            } else {
                return n; // No match - so exit. Not an exception.
            }
        } while (n != BreakIterator.DONE);
        return n;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (this == obj)
            return true;
        if (getClass() != obj.getClass())
            return false;
        SimpleFilteredSentenceBreakIterator other = (SimpleFilteredSentenceBreakIterator) obj;
        return delegate.equals(other.delegate) && text.equals(other.text) && backwardsTrie.equals(other.backwardsTrie)
                && forwardsPartialTrie.equals(other.forwardsPartialTrie);
    }

    @Override
    public int hashCode() {
        return (forwardsPartialTrie.hashCode() * 39) + (backwardsTrie.hashCode() * 11) + delegate.hashCode();
    }

    @Override
    public Object clone() {
        SimpleFilteredSentenceBreakIterator other = (SimpleFilteredSentenceBreakIterator) super.clone();
        return other;
    }

    @Override
    public int first() {
        return delegate.first();
    }

    @Override
    public int last() {
        return delegate.last();
    }

    @Override
    public int next(int n) {
        // TODO
        throw new UnsupportedOperationException("next(int) is not yet implemented");
    }

    @Override
    public int previous() {
        // TODO
        throw new UnsupportedOperationException("previous() is not yet implemented");
    }

    @Override
    public int following(int offset) {
        // TODO
        throw new UnsupportedOperationException("following(int) is not yet implemented");
    }

    @Override
    public int current() {
        return delegate.current();
    }

    @Override
    public int preceding(int offset) {
        // TODO
        throw new UnsupportedOperationException("preceding(int) is not yet implemented");
    }

    @Override
    public CharacterIterator getText() {
        return delegate.getText();
    }

    @Override
    public void setText(CharacterIterator newText) {
        delegate.setText(newText);
    }

    public static class Builder extends FilteredBreakIteratorBuilder {
        /**
         * filter set to store all exceptions
         */
        private HashSet<String> filterSet = new HashSet<String>();

        static final int PARTIAL = (1 << 0); // < partial - need to run through forward trie
        static final int MATCH = (1 << 1); // < exact match - skip this one.
        static final int SuppressInReverse = (1 << 0);
        static final int AddToForward = (1 << 1);

        /**
         * Create SimpleFilteredBreakIteratorBuilder using given locale
         * @param loc the locale to get filtered iterators
         */
        public Builder(ULocale loc) {
            ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(
                    ICUData.ICU_BRKITR_BASE_NAME, loc);
            ICUResourceBundle exceptions = rb.findWithFallback("exceptions");
            if (exceptions != null) {
                ICUResourceBundle breaks = exceptions.findWithFallback("SentenceBreak");
    
                if (breaks != null) {
                    for (int index = 0, size = breaks.getSize(); index < size; ++index) {
                        ICUResourceBundle b = (ICUResourceBundle) breaks.get(index);
                        String br = b.getString();
                        filterSet.add(br);
                    }
                }
            } // else - no exceptions.
        }

        /**
         * Create SimpleFilteredBreakIteratorBuilder with no exception
         */
        public Builder() {
            filterSet = new HashSet<String>();
        }

        @Override
        public boolean suppressBreakAfter(String str) {
            if (filterSet == null) {
                filterSet = new HashSet<String>();
            }
            return filterSet.add(str);
        }

        @Override
        public boolean unsuppressBreakAfter(String str) {
            if (filterSet == null) {
                return false;
            } else {
                return filterSet.remove(str);
            }
        }

        @Override
        public BreakIterator build(BreakIterator adoptBreakIterator) {
            if( filterSet.isEmpty() ) {
                // Short circuit - nothing to except.
                return adoptBreakIterator;
            }
            
            CharsTrieBuilder builder = new CharsTrieBuilder();
            CharsTrieBuilder builder2 = new CharsTrieBuilder();

            int revCount = 0;
            int fwdCount = 0;

            int subCount = filterSet.size();
            String[] ustrs = new String[subCount];
            int[] partials = new int[subCount];

            CharsTrie backwardsTrie = null; // i.e. ".srM" for Mrs.
            CharsTrie forwardsPartialTrie = null; // Has ".a" for "a.M."

            int i = 0;
            for (String s : filterSet) {
                ustrs[i] = s; // copy by value?
                partials[i] = 0; // default: no partial
                i++;
            }

            for (i = 0; i < subCount; i++) {
                int nn = ustrs[i].indexOf('.'); // TODO: non-'.' abbreviations
                if (nn > -1 && (nn + 1) != ustrs[i].length()) {
                    // is partial.
                    // is it unique?
                    int sameAs = -1;
                    for (int j = 0; j < subCount; j++) {
                        if (j == i)
                            continue;
                        if (ustrs[i].regionMatches(0, ustrs[j], 0, nn + 1)) {
                            if (partials[j] == 0) { // hasn't been processed yet
                                partials[j] = SuppressInReverse | AddToForward;
                            } else if ((partials[j] & SuppressInReverse) != 0) {
                                sameAs = j; // the other entry is already in the reverse table.
                            }
                        }
                    }

                    if ((sameAs == -1) && (partials[i] == 0)) {
                        StringBuilder prefix = new StringBuilder(ustrs[i].substring(0, nn + 1));
                        // first one - add the prefix to the reverse table.
                        prefix.reverse();
                        builder.add(prefix, PARTIAL);
                        revCount++;
                        partials[i] = SuppressInReverse | AddToForward;
                    }
                }
            }

            for (i = 0; i < subCount; i++) {
                if (partials[i] == 0) {
                    StringBuilder reversed = new StringBuilder(ustrs[i]).reverse();
                    builder.add(reversed, MATCH);
                    revCount++;
                } else {
                    // an optimization would be to only add the portion after the '.'
                    // for example, for "Ph.D." we store ".hP" in the reverse table. We could just store "D." in the
                    // forward,
                    // instead of "Ph.D." since we already know the "Ph." part is a match.
                    // would need the trie to be able to hold 0-length strings, though.
                    builder2.add(ustrs[i], MATCH); // forward
                    fwdCount++;
                }
            }

            if (revCount > 0) {
                backwardsTrie = builder.build(StringTrieBuilder.Option.FAST);
            }

            if (fwdCount > 0) {
                forwardsPartialTrie = builder2.build(StringTrieBuilder.Option.FAST);
            }
            return new SimpleFilteredSentenceBreakIterator(adoptBreakIterator, forwardsPartialTrie, backwardsTrie);
        }
    }
}
