/*
**********************************************************************
*   Copyright (C) 1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   11/17/99    aliu        Creation.
**********************************************************************
*/
#include "unicode/unistr.h"
#include "unicode/uniset.h"
#include "rbt_set.h"
#include "rbt_rule.h"
#include "cmemory.h"

U_CDECL_BEGIN
static void U_EXPORT2 U_CALLCONV _deleteRule(void *rule) {
    delete (U_NAMESPACE_QUALIFIER TransliterationRule *)rule;
}
U_CDECL_END

//----------------------------------------------------------------------
// BEGIN Debugging support
//----------------------------------------------------------------------

// #define DEBUG_RBT

#ifdef DEBUG_RBT
#include <stdio.h>
#include "charstr.h"

/**
 * @param appendTo result is appended to this param.
 * @param input the string being transliterated
 * @param pos the index struct
 */
static UnicodeString& _formatInput(UnicodeString &appendTo,
                                   const UnicodeString& input,
                                   const UTransPosition& pos) {
    // Output a string of the form aaa{bbb|ccc|ddd}eee, where
    // the {} indicate the context start and limit, and the ||
    // indicate the start and limit.
    if (0 <= pos.contextStart &&
        pos.contextStart <= pos.start &&
        pos.start <= pos.limit &&
        pos.limit <= pos.contextLimit &&
        pos.contextLimit <= input.length()) {

        UnicodeString a, b, c, d, e;
        input.extractBetween(0, pos.contextStart, a);
        input.extractBetween(pos.contextStart, pos.start, b);
        input.extractBetween(pos.start, pos.limit, c);
        input.extractBetween(pos.limit, pos.contextLimit, d);
        input.extractBetween(pos.contextLimit, input.length(), e);
        appendTo.append(a).append((UChar)123/*{*/).append(b).
            append((UChar)124/*|*/).append(c).append((UChar)124/*|*/).append(d).
            append((UChar)125/*}*/).append(e);
    } else {
        appendTo.append("INVALID UTransPosition");
        //appendTo.append((UnicodeString)"INVALID UTransPosition {cs=" +
        //                pos.contextStart + ", s=" + pos.start + ", l=" +
        //                pos.limit + ", cl=" + pos.contextLimit + "} on " +
        //                input);
    }
    return appendTo;
}

// Append a hex string to the target
UnicodeString& _appendHex(uint32_t number,
                          int32_t digits,
                          UnicodeString& target) {
    static const UChar digitString[] = {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
        0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
    };
    while (digits--) {
        target += digitString[(number >> (digits*4)) & 0xF];
    }
    return target;
}

// Replace nonprintable characters with unicode escapes
UnicodeString& _escape(const UnicodeString &source,
                       UnicodeString &target) {
    for (int32_t i = 0; i < source.length(); ) {
        UChar32 ch = source.char32At(i);
        i += UTF_CHAR_LENGTH(ch);
        if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| ch > 0x7E) {
            if (ch <= 0xFFFF) {
                target += "\\u";
                _appendHex(ch, 4, target);
            } else {
                target += "\\U";
                _appendHex(ch, 8, target);
            }
        } else {
            target += ch;
        }
    }
    return target;
}

inline void _debugOut(const char* msg, TransliterationRule* rule,
                      const Replaceable& theText, UTransPosition& pos) {
    UnicodeString buf(msg, "");
    if (rule) {
        UnicodeString r;
        rule->toRule(r, TRUE);
        buf.append((UChar)32).append(r);
    }
    buf.append(UnicodeString(" => ", ""));
    UnicodeString* text = (UnicodeString*)&theText;
    _formatInput(buf, *text, pos);
    UnicodeString esc;
    _escape(buf, esc);
    CharString cbuf(esc);
    printf("%s\n", (char*) cbuf);
}

#else
#define _debugOut(msg, rule, theText, pos)
#endif

//----------------------------------------------------------------------
// END Debugging support
//----------------------------------------------------------------------

// Fill the precontext and postcontext with the patterns of the rules
// that are masking one another.
static void maskingError(const U_NAMESPACE_QUALIFIER TransliterationRule& rule1,
                         const U_NAMESPACE_QUALIFIER TransliterationRule& rule2,
                         UParseError& parseError) {
    U_NAMESPACE_QUALIFIER UnicodeString r;
    int32_t len;

    parseError.line = parseError.offset = -1;
    
    // for pre-context
    rule1.toRule(r, FALSE);
    len = uprv_min(r.length(), U_PARSE_CONTEXT_LEN-1);
    r.extract(0, len, parseError.preContext);
    parseError.preContext[len] = 0;   
    
    //for post-context
    r.truncate(0);
    rule2.toRule(r, FALSE);
    len = uprv_min(r.length(), U_PARSE_CONTEXT_LEN-1);
    r.extract(0, len, parseError.postContext);
    parseError.postContext[len] = 0;   
}

U_NAMESPACE_BEGIN

const char TransliterationRuleSet::fgClassID=0;

/**
 * Construct a new empty rule set.
 */
TransliterationRuleSet::TransliterationRuleSet(UErrorCode& status) : UObject() {
    ruleVector = new UVector(&_deleteRule, NULL, status);
    rules = NULL;
    maxContextLength = 0;
    if (ruleVector == NULL) {
        status = U_MEMORY_ALLOCATION_ERROR;
    }
}

/**
 * Copy constructor.
 */
TransliterationRuleSet::TransliterationRuleSet(const TransliterationRuleSet& other) :
    UObject(other),
    ruleVector(0),
    rules(0),
    maxContextLength(other.maxContextLength) {

    int32_t i, len;
    uprv_memcpy(index, other.index, sizeof(index));
    UErrorCode status = U_ZERO_ERROR;
    ruleVector = new UVector(&_deleteRule, NULL, status);
    if (other.ruleVector != 0 && ruleVector != 0 && U_SUCCESS(status)) {
        len = other.ruleVector->size();
        for (i=0; i<len && U_SUCCESS(status); ++i) {
            ruleVector->addElement(new TransliterationRule(
              *(TransliterationRule*)other.ruleVector->elementAt(i)), status);
        }
    }
    if (other.rules != 0) {
        UParseError p;
        freeze(p, status);
    }
}

/**
 * Destructor.
 */
TransliterationRuleSet::~TransliterationRuleSet() {
    delete ruleVector; // This deletes the contained rules
    uprv_free(rules);
}

void TransliterationRuleSet::setData(const TransliterationRuleData* d) {
    /**
     * We assume that the ruleset has already been frozen.
     */
    int32_t len = index[256]; // see freeze()
    for (int32_t i=0; i<len; ++i) {
        rules[i]->setData(d);
    }
}

/**
 * Return the maximum context length.
 * @return the length of the longest preceding context.
 */
int32_t TransliterationRuleSet::getMaximumContextLength(void) const {
    return maxContextLength;
}

/**
 * Add a rule to this set.  Rules are added in order, and order is
 * significant.  The last call to this method must be followed by
 * a call to <code>freeze()</code> before the rule set is used.
 *
 * <p>If freeze() has already been called, calling addRule()
 * unfreezes the rules, and freeze() must be called again.
 *
 * @param adoptedRule the rule to add
 */
void TransliterationRuleSet::addRule(TransliterationRule* adoptedRule,
                                     UErrorCode& status) {
    if (U_FAILURE(status)) {
        delete adoptedRule;
        return;
    }
    ruleVector->addElement(adoptedRule, status);

    int32_t len;
    if ((len = adoptedRule->getContextLength()) > maxContextLength) {
        maxContextLength = len;
    }

    uprv_free(rules);
    rules = 0;
}

/**
 * Check this for masked rules and index it to optimize performance.
 * The sequence of operations is: (1) add rules to a set using
 * <code>addRule()</code>; (2) freeze the set using
 * <code>freeze()</code>; (3) use the rule set.  If
 * <code>addRule()</code> is called after calling this method, it
 * invalidates this object, and this method must be called again.
 * That is, <code>freeze()</code> may be called multiple times,
 * although for optimal performance it shouldn't be.
 */
void TransliterationRuleSet::freeze(UParseError& parseError,UErrorCode& status) {
    /* Construct the rule array and index table.  We reorder the
     * rules by sorting them into 256 bins.  Each bin contains all
     * rules matching the index value for that bin.  A rule
     * matches an index value if string whose first key character
     * has a low byte equal to the index value can match the rule.
     *
     * Each bin contains zero or more rules, in the same order
     * they were found originally.  However, the total rules in
     * the bins may exceed the number in the original vector,
     * since rules that have a variable as their first key
     * character will generally fall into more than one bin.
     *
     * That is, each bin contains all rules that either have that
     * first index value as their first key character, or have
     * a set containing the index value as their first character.
     */
    int32_t n = ruleVector->size();
    int32_t j;
    int16_t x;
    UVector v(2*n, status); // heuristic; adjust as needed

    if (U_FAILURE(status)) {
        return;
    }

    /* Precompute the index values.  This saves a LOT of time.
     * Be careful not to call malloc(0).
     */
    int16_t* indexValue = (int16_t*) uprv_malloc( sizeof(int16_t) * (n > 0 ? n : 1) );
    /* test for NULL */
    if (indexValue == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    for (j=0; j<n; ++j) {
        TransliterationRule* r = (TransliterationRule*) ruleVector->elementAt(j);
        indexValue[j] = r->getIndexValue();
    }
    for (x=0; x<256; ++x) {
        index[x] = v.size();
        for (j=0; j<n; ++j) {
            if (indexValue[j] >= 0) {
                if (indexValue[j] == x) {
                    v.addElement(ruleVector->elementAt(j), status);
                }
            } else {
                // If the indexValue is < 0, then the first key character is
                // a set, and we must use the more time-consuming
                // matchesIndexValue check.  In practice this happens
                // rarely, so we seldom tread this code path.
                TransliterationRule* r = (TransliterationRule*) ruleVector->elementAt(j);
                if (r->matchesIndexValue((uint8_t)x)) {
                    v.addElement(r, status);
                }
            }
        }
    }
    uprv_free(indexValue);
    index[256] = v.size();

    /* Freeze things into an array.
     */
    uprv_free(rules); // Contains alias pointers

    /* You can't do malloc(0)! */
    if (v.size() == 0) {
        rules = NULL;
        return;
    }
    rules = (TransliterationRule **)uprv_malloc(v.size() * sizeof(TransliterationRule *));
    /* test for NULL */
    if (rules == 0) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    for (j=0; j<v.size(); ++j) {
        rules[j] = (TransliterationRule*) v.elementAt(j);
    }

    // TODO Add error reporting that indicates the rules that
    //      are being masked.
    //UnicodeString errors;

    /* Check for masking.  This is MUCH faster than our old check,
     * which was each rule against each following rule, since we
     * only have to check for masking within each bin now.  It's
     * 256*O(n2^2) instead of O(n1^2), where n1 is the total rule
     * count, and n2 is the per-bin rule count.  But n2<<n1, so
     * it's a big win.
     */
    for (x=0; x<256; ++x) {
        for (j=index[x]; j<index[x+1]-1; ++j) {
            TransliterationRule* r1 = rules[j];
            for (int32_t k=j+1; k<index[x+1]; ++k) {
                TransliterationRule* r2 = rules[k];
                if (r1->masks(*r2)) {
//|                 if (errors == null) {
//|                     errors = new StringBuffer();
//|                 } else {
//|                     errors.append("\n");
//|                 }
//|                 errors.append("Rule " + r1 + " masks " + r2);
                    status = U_RULE_MASK_ERROR;
                    maskingError(*r1, *r2, parseError);
                    return;
                }
            }
        }
    }

    //if (errors != null) {
    //    throw new IllegalArgumentException(errors.toString());
    //}
}

/**
 * Transliterate the given text with the given UTransPosition
 * indices.  Return TRUE if the transliteration should continue
 * or FALSE if it should halt (because of a U_PARTIAL_MATCH match).
 * Note that FALSE is only ever returned if isIncremental is TRUE.
 * @param text the text to be transliterated
 * @param pos the position indices, which will be updated
 * @param incremental if TRUE, assume new text may be inserted
 * at index.limit, and return FALSE if thre is a partial match.
 * @return TRUE unless a U_PARTIAL_MATCH has been obtained,
 * indicating that transliteration should stop until more text
 * arrives.
 */
UBool TransliterationRuleSet::transliterate(Replaceable& text,
                                            UTransPosition& pos,
                                            UBool incremental) {
    int16_t indexByte = (int16_t) (text.char32At(pos.start) & 0xFF);
    for (int32_t i=index[indexByte]; i<index[indexByte+1]; ++i) {
        UMatchDegree m = rules[i]->matchAndReplace(text, pos, incremental);
        switch (m) {
        case U_MATCH:
            _debugOut("match", rules[i], text, pos);
            return TRUE;
        case U_PARTIAL_MATCH:
            _debugOut("partial match", rules[i], text, pos);
            return FALSE;
        default: /* Ram: added default to make GCC happy */
            break;
        }
    }
    // No match or partial match from any rule
    pos.start += UTF_CHAR_LENGTH(text.char32At(pos.start));
    _debugOut("no match", NULL, text, pos);
    return TRUE;
}

/**
 * Create rule strings that represents this rule set.
 */
UnicodeString& TransliterationRuleSet::toRules(UnicodeString& ruleSource,
                                               UBool escapeUnprintable) const {
    int32_t i;
    int32_t count = ruleVector->size();
    ruleSource.truncate(0);
    for (i=0; i<count; ++i) {
        if (i != 0) {
            ruleSource.append((UChar) 0x000A /*\n*/);
        }
        TransliterationRule *r =
            (TransliterationRule*) ruleVector->elementAt(i);
        r->toRule(ruleSource, escapeUnprintable);
    }
    return ruleSource;
}

/**
 * Return the set of all characters that may be modified
 * (getTarget=false) or emitted (getTarget=true) by this set.
 */
UnicodeSet& TransliterationRuleSet::getSourceTargetSet(UnicodeSet& result,
						       UBool getTarget) const {
    result.clear();
    int32_t count = ruleVector->size();
    for (int32_t i=0; i<count; ++i) {
	TransliterationRule* r =
	    (TransliterationRule*) ruleVector->elementAt(i);
	if (getTarget) {
	    r->addTargetSetTo(result);
	} else {
	    r->addSourceSetTo(result);
	}
    }
    return result;
}

U_NAMESPACE_END
