/*
***************************************************************************
*   Copyright (C) 2002-2009 International Business Machines Corporation   *
*   and others. All rights reserved.                                      *
***************************************************************************
*/
package com.ibm.icu.text;

import java.text.ParsePosition;
import java.util.HashMap;

import com.ibm.icu.lang.UCharacter;

class RBBISymbolTable implements SymbolTable{
    
    String               fRules;
    HashMap<String, RBBISymbolTableEntry> fHashTable;
    RBBIRuleScanner      fRuleScanner;

    // These next two fields are part of the mechanism for passing references to
    //   already-constructed UnicodeSets back to the UnicodeSet constructor
    //   when the pattern includes $variable references.
    String               ffffString;
    UnicodeSet           fCachedSetLookup;
    
    
    
    static class RBBISymbolTableEntry  { 
        String          key;
        RBBINode        val;
    }

    
    RBBISymbolTable(RBBIRuleScanner rs, String rules) {
        fRules = rules;
        fRuleScanner = rs;
        fHashTable = new HashMap<String, RBBISymbolTableEntry>();
        ffffString = "\uffff";
    }

    //
    //  RBBISymbolTable::lookup       This function from the abstract symbol table inteface
    //                                looks up a variable name and returns a UnicodeString
    //                                containing the substitution text.
    //
    //                                The variable name does NOT include the leading $.
    //
    public char[] lookup(String s) {
        RBBISymbolTableEntry el;
        RBBINode varRefNode;
        RBBINode exprNode;

        RBBINode usetNode;
        String retString;

        el = fHashTable.get(s);
        if (el == null) {
            return null;
        }

        // Walk through any chain of variable assignments that ultimately resolve to a Set Ref.
        varRefNode = el.val;
        while (varRefNode.fLeftChild.fType == RBBINode.varRef) {
            varRefNode = varRefNode.fLeftChild;
        }

        exprNode = varRefNode.fLeftChild; // Root node of expression for variable
        if (exprNode.fType == RBBINode.setRef) {
            // The $variable refers to a single UnicodeSet
            //   return the ffffString, which will subsequently be interpreted as a
            //   stand-in character for the set by RBBISymbolTable::lookupMatcher()
            usetNode = exprNode.fLeftChild;
            fCachedSetLookup = usetNode.fInputSet;
            retString = ffffString;
        } else {
            // The variable refers to something other than just a set.
            // This is an error in the rules being compiled.  $Variables inside of UnicodeSets
            //   must refer only to another set, not to some random non-set expression.
            //   Note:  single characters are represented as sets, so they are ok.
            fRuleScanner.error(RBBIRuleBuilder.U_BRK_MALFORMED_SET);
            retString = exprNode.fText;
            fCachedSetLookup = null;
        }
        return retString.toCharArray();
    }

    //
    //  RBBISymbolTable::lookupMatcher   This function from the abstract symbol table
    //                                   interface maps a single stand-in character to a
    //                                   pointer to a Unicode Set.   The Unicode Set code uses this
    //                                   mechanism to get all references to the same $variable
    //                                   name to refer to a single common Unicode Set instance.
    //
    //    This implementation cheats a little, and does not maintain a map of stand-in chars
    //    to sets.  Instead, it takes advantage of the fact that  the UnicodeSet
    //    constructor will always call this function right after calling lookup(),
    //    and we just need to remember what set to return between these two calls.
    public UnicodeMatcher lookupMatcher(int ch) {
        UnicodeSet retVal = null;
        if (ch == 0xffff) {
            retVal = fCachedSetLookup;
            fCachedSetLookup = null;
        }
        return retVal;
    }

    //
    // RBBISymbolTable::parseReference   This function from the abstract symbol table interface
    //                                   looks for a $variable name in the source text.
    //                                   It does not look it up, only scans for it.
    //                                   It is used by the UnicodeSet parser.
    //
    public String parseReference(String text, ParsePosition pos, int limit) {
        int start = pos.getIndex();
        int i = start;
        String result = "";
        while (i < limit) {
            int c = UTF16.charAt(text, i);
            if ((i == start && !UCharacter.isUnicodeIdentifierStart(c))
                    || !UCharacter.isUnicodeIdentifierPart(c)) {
                break;
            }
            i += UTF16.getCharCount(c);
        }
        if (i == start) { // No valid name chars
            return result; // Indicate failure with empty string
        }
        pos.setIndex(i);
        result = text.substring(start, i);
        return result;
    }

    //
    // RBBISymbolTable::lookupNode      Given a key (a variable name), return the
    //                                  corresponding RBBI Node.  If there is no entry
    //                                  in the table for this name, return NULL.
    //
    RBBINode lookupNode(String key) {

        RBBINode retNode = null;
        RBBISymbolTableEntry el;

        el = fHashTable.get(key);
        if (el != null) {
            retNode = el.val;
        }
        return retNode;
    }

    //
    //    RBBISymbolTable::addEntry     Add a new entry to the symbol table.
    //                                  Indicate an error if the name already exists -
    //                                    this will only occur in the case of duplicate
    //                                    variable assignments.
    //
    void addEntry(String key, RBBINode val) {
        RBBISymbolTableEntry e;
        e = fHashTable.get(key);
        if (e != null) {
            fRuleScanner.error(RBBIRuleBuilder.U_BRK_VARIABLE_REDFINITION);
            return;
        }

        e = new RBBISymbolTableEntry();
        e.key = key;
        e.val = val;
        fHashTable.put(e.key, e);
    }

    //
    //  RBBISymbolTable::print    Debugging function, dump out the symbol table contents.
    //
    ///CLOVER:OFF
    void rbbiSymtablePrint() {
        System.out
                .print("Variable Definitions\n"
                        + "Name               Node Val     String Val\n"
                        + "----------------------------------------------------------------------\n");

        RBBISymbolTableEntry[] syms = fHashTable.values().toArray(new RBBISymbolTableEntry[0]);

        for (int i = 0; i < syms.length; i++) {
            RBBISymbolTableEntry s = syms[i];

            System.out.print("  " + s.key + "  "); // TODO:  format output into columns.
            System.out.print("  " + s.val + "  ");
            System.out.print(s.val.fLeftChild.fText);
            System.out.print("\n");
        }

        System.out.println("\nParsed Variable Definitions\n");
        for (int i = 0; i < syms.length; i++) {
            RBBISymbolTableEntry s = syms[i];
            System.out.print(s.key);
            s.val.fLeftChild.printTree(true);
            System.out.print("\n");
        }
    }
    ///CLOVER:ON
    
}
