package hiro.yoshioka.ast.sql.util;

import hiro.yoshioka.ast.sql.IParserException;
import hiro.yoshioka.ast.sql.IQueryTableExpression;
import hiro.yoshioka.ast.sql.ISchemaTableColumn;
import hiro.yoshioka.ast.sql.IToken;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ASTAssist {
	protected Log fLogger = LogFactory.getLog(this.getClass());
	public static final int ASSIST_NOTHING = 0;

	public static final int ASSIST_COLUMN = 10;

	public static final int ASSIST_COLUMN_OR_KEY = 60;

	public static final int ASSIST_TABLE = 100;

	public static final int ASSIST_KEY_WORD = 1000;

	protected int fAssist = ASSIST_NOTHING;

	public ISchemaTableColumn fASTSchemaTableColumn;

	private IParserException fParseException;

	public IQueryTableExpression fASTQueryTableExpressionClause;

	BackWord fBackWord;

	Set<String> fKeyWordList = new LinkedHashSet<String>();

	public ASTAssist(int id) {
		fAssist = id;
	}

	public ASTAssist(int id, Throwable e) {
		this(id);
		if (e instanceof IParserException) {
			fParseException = (IParserException) e;
			fKeyWordList.addAll(fParseException.getExpectedTokenList());
		}
		if (fAssist == ASSIST_COLUMN_OR_KEY) {
			for (String key : fKeyWordList) {
				if (key.equals("<STRING_LITERAL>")) {
					fAssist = ASSIST_COLUMN;
					break;
				}
			}
			if (fAssist == ASSIST_COLUMN_OR_KEY) {
				fAssist = ASSIST_KEY_WORD;
			}
		}
	}

	public ASTAssist(String[] keys) {
		for (int i = 0; i < keys.length; i++) {
			fKeyWordList.add(keys[i]);
		}
		fAssist = ASSIST_KEY_WORD;
	}

	public ASTAssist(List lists) {
		this((String[]) lists.toArray(new String[lists.size()]));
	}

	/**
	 * @param assist_table2
	 * @param queryTableExpressionClause
	 */
	public ASTAssist(int id, IQueryTableExpression queryTableExpressionClause) {
		this(id);
		fASTQueryTableExpressionClause = queryTableExpressionClause;
	}

	/**
	 * @param assist_column2
	 * @param schemaTableColumn
	 */
	public ASTAssist(int id, ISchemaTableColumn schemaTableColumn) {
		this(id);
		fASTSchemaTableColumn = schemaTableColumn;
	}

	public IToken getErrorToken() {
		if (fParseException == null) {
			return null;
		}
		return fParseException.getCurrentToken();
	}

	public String[] getKeyWords() {
		return (String[]) fKeyWordList.toArray(new String[fKeyWordList.size()]);
	}

	public String[] getKeyWords(BackWord back) {
		List<String> list = new ArrayList<String>();
		for (String key : fKeyWordList) {
			if (key.startsWith(back.getLastWord().toUpperCase())) {
				list.add(key);
			}
		}
		return (String[]) list.toArray(new String[list.size()]);
	}

	public String toString() {
		StringBuffer buf = new StringBuffer("Assist:");
		switch (fAssist) {
		case ASSIST_NOTHING:
			buf.append("Nothing..");
			break;
		case ASSIST_COLUMN:
			buf.append("Column..");// buf.append(fTableList);
			break;
		case ASSIST_TABLE:
			buf.append("Table..");
			break;
		case ASSIST_KEY_WORD:
			buf.append("Key..").append(fKeyWordList);
			break;
		}
		// for(int i=0;i<fExpectedList.size();i++){
		// if(i==0){
		// buf.append("
		// [EXP(").append(fExpectedList.size()).append("):").append(fExpectedList.get(i));
		// } else if(i<3){
		// buf.append(fExpectedList.get(i));
		// } else {
		// buf.append(" ...]" );
		// break;
		// }
		// buf.append("," );
		// }
		return buf.toString();
	}

	/**
	 * @param holder
	 */
	// public void setTableHolder(ASTEditorTableListHolder holder) {
	// fTableList=holder;
	// }
	// public ASTEditorTableListHolder getTableHolder(){
	// return fTableList;
	// }
	/**
	 * @return
	 */
	public boolean isNothing() {
		return fAssist == ASSIST_NOTHING;
	}

	/**
	 * @return
	 */
	public boolean isColumn() {
		return fAssist == ASSIST_COLUMN;
	}

	/**
	 * @return
	 */
	public boolean isTable() {
		return fAssist == ASSIST_TABLE;
	}

	/**
	 * @return
	 */
	public boolean isKey() {
		return fAssist == ASSIST_KEY_WORD;
	}

	/**
	 * @return
	 */
	public int getType() {
		return fAssist;
	}

	public void resetAssistType2Table() {
		fAssist = ASSIST_TABLE;
	}

	/**
	 * @param expectedTokens
	 */
	public void setExpedtedTokens(Iterator expectedTokens) {
		for (; expectedTokens.hasNext();) {
			String exstr = (String) expectedTokens.next();
			boolean append = true;
			for (String key : fKeyWordList) {
				if (exstr.equals(key)) {
					append = false;
					break;
				}
			}
			if (append) {
				fKeyWordList.add(exstr);
			}
		}
	}

	/**
	 * @param backWord
	 */
	public void setBackWord(BackWord backWord) {
		fBackWord = backWord;
	}

	public void addKeyWords(String[] keys) {
		for (String key : keys) {
			fKeyWordList.add(key);
		}
	}
}