package org.eclipse.dltk.xotcl.internal.core.parser;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.ast.ASTListNode;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.Modifiers;
import org.eclipse.dltk.ast.declarations.Argument;
import org.eclipse.dltk.ast.declarations.Declaration;
import org.eclipse.dltk.ast.declarations.FieldDeclaration;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.compiler.ISourceElementRequestor;
import org.eclipse.dltk.compiler.SourceElementRequestVisitor;
import org.eclipse.dltk.compiler.problem.DefaultProblem;
import org.eclipse.dltk.compiler.problem.IProblemReporter;
import org.eclipse.dltk.compiler.problem.ProblemSeverities;
import org.eclipse.dltk.tcl.ast.TclConstants;
import org.eclipse.dltk.tcl.ast.TclStatement;
import org.eclipse.dltk.tcl.ast.expressions.TclBlockExpression;
import org.eclipse.dltk.tcl.ast.expressions.TclExecuteExpression;
import org.eclipse.dltk.tcl.core.TclKeywordsManager;
import org.eclipse.dltk.tcl.internal.parser.TclParseUtils;
import org.eclipse.dltk.xotcl.core.IXOTclModifiers;
import org.eclipse.dltk.xotcl.core.TclParseUtil;
import org.eclipse.dltk.xotcl.core.ast.TclGlobalVariableDeclaration;
import org.eclipse.dltk.xotcl.core.ast.TclPackageDeclaration;
import org.eclipse.dltk.xotcl.core.ast.TclUpvarVariableDeclaration;
import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclFieldDeclaration;
import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclMethodCallStatement;
import org.eclipse.dltk.xotcl.core.ast.xotcl.XOTclVariableDeclaration;

public class XOTclSourceElementRequestVisitor extends
		SourceElementRequestVisitor {

	private Stack namespacesLevel = new Stack();
	private Stack exitStack = new Stack();
	private IProblemReporter fReporter;

	private String removeLastSegment(String s, String delimeter) {
		if (s.indexOf("::") == -1) {
			return "";
		}
		int pos = s.length() - 1;
		while (s.charAt(pos) != ':') {
			pos--;
		}
		if (pos > 1) {
			return s.substring(0, pos - 1);
		} else {
			return "::";
		}
	}

	private class ExitFromType {
		private int level;
		private int end;
		private boolean exitFromModule;
		private boolean pop;
		public boolean created = false;

		public ExitFromType(int level, int declEnd, boolean mod, boolean pop) {
			this.level = level;
			this.end = declEnd;
			this.exitFromModule = mod;
			this.pop = pop;
		}

		public ExitFromType(int level, int declEnd, boolean mod, boolean pop,
				boolean created) {
			this(level, declEnd, mod, pop);
			this.created = created;
		}

		public void go() {
			for (int i = 0; i < this.level; i++) {
				XOTclSourceElementRequestVisitor.this.fRequestor
						.exitType(this.end);
			}
			if (this.exitFromModule) {
				XOTclSourceElementRequestVisitor.this.fRequestor
						.exitModuleRoot();
			}
			if (this.pop) {
				XOTclSourceElementRequestVisitor.this.namespacesLevel.pop();
			}
		}
	}

	private String getEnclosingNamespace() {
		String s = (String) this.namespacesLevel.peek();
		return s;

	}

	/**
	 * Enters into required type (if type doesn't exists, creates it). If name
	 * is fully-qualified (starting with a "::") then it is always resolved
	 * globally. Else search are done first in current namespace, than in
	 * global. Flags <code>onlyCurrent</code> allows to search
	 * <em>not qualified</em> names only in current namespace. If type doesn't
	 * exists, it will be created. If name is qualified, it will be created
	 * globally, else in current namespace.s
	 * 
	 * @param decl
	 *            expression containing typedeclaration correct source ranges
	 *            setup
	 * @param name
	 *            name containing a type
	 * @param onlyCurrent
	 * @return ExitFromType object, that should be called to exit
	 */
	private ExitFromType resolveType(Declaration decl, String name,
			boolean onlyCurrent) {
		String type = this.removeLastSegment(name, "::");
		while (type.length() > 2 && type.endsWith("::")) {
			type = type.substring(0, type.length() - 2);
		}

		if (type.length() == 0) {
			return new ExitFromType(0, 0, false, false);
		}

		if (type.equals("::")) {
			this.fRequestor.enterModuleRoot();
			this.namespacesLevel.push("::");
			return new ExitFromType(0, decl.sourceEnd(), true, true);
		}

		boolean fqn = type.startsWith("::");

		String fullyQualified = type;
		if (!fqn) { // make name fully-qualified
			String e = this.getEnclosingNamespace();
			if (e == null) {
				throw new AssertionError("there are no enclosing namespace!");
			}
			if (!e.endsWith("::")) {
				e += "::";
			}
			fullyQualified = e + type;
		}

		// first, try existent
		if (this.fRequestor.enterTypeAppend(type, "::")) {
			this.namespacesLevel.push(fullyQualified);
			// if( type.startsWith("::")) {
			// String name2 = type.substring(2);
			// String[] split = name2.split("::");
			// return new ExitFromType(split.length, decl.sourceEnd(), false,
			// true);
			// }
			// else {
			// String name2 = type;
			// String[] split = name2.split("::");
			// return new ExitFromType(split.length, decl.sourceEnd(), false,
			// true);
			// }
			return new ExitFromType(1/* split.length */, decl.sourceEnd(),
					false, true);
		}
		// This is not correct for Tcl
		// else if (!fqn && !onlyCurrent) { // look in global
		// if (this.fNodes.size() > 0
		// && this.fNodes.get(0) instanceof ModuleDeclaration) {
		// ModuleDeclaration module = (ModuleDeclaration) this.fNodes
		// .get(0);
		// TypeDeclaration t = TclParseUtil.findTclTypeDeclarationFrom(
		// module, decl);
		// if (t != null) {
		// List nodes = TclParseUtil.findLevelsTo(module, t);
		// String elementFQN = TclParseUtil.getElementFQN(nodes, "::");
		// if (this.fRequestor.enterTypeAppend(elementFQN, "::")) {
		// this.namespacesLevel.push("::" + type);
		// return new ExitFromType(1, decl.sourceEnd(), false,
		// true);
		// }
		// }
		// }
		// }

		// create it
		// Lets add warning in any case.
		int needEnterLeave = 0;
		String[] split = null;
		String e = this.getEnclosingNamespace();
		if (e == null) {
			throw new AssertionError("there are no enclosing namespace!");
		}
		boolean entered = false;
		boolean exitFromModule = false;
		if (e.length() > 0 && !fqn) {
			// We need to report warning here.
			entered = this.fRequestor.enterTypeAppend(e, "::");
		}
		if (fqn || !entered) {
			split = fullyQualified.substring(2).split("::");
			this.fRequestor.enterModuleRoot();
			exitFromModule = true;
		} else {
			if (!entered) {
				throw new AssertionError("can't enter to enclosing namespace!");
			}
			needEnterLeave++;
			split = type.split("::");
		}

		for (int i = 0; i < split.length; ++i) {
			if (split[i].length() > 0) {
				needEnterLeave++;
				if (!this.fRequestor.enterTypeAppend(split[i], "::")) {
					ISourceElementRequestor.TypeInfo ti = new ISourceElementRequestor.TypeInfo();
					ti.modifiers = this.getModifiers(decl);

					ti.name = split[i];
					ti.nameSourceStart = decl.getNameStart();
					ti.nameSourceEnd = decl.getNameEnd() - 1;
					ti.declarationStart = decl.sourceStart();
					this.fRequestor.enterType(ti);
				}
			}
		}
		this.namespacesLevel.push(fullyQualified);
		return new ExitFromType(needEnterLeave, decl.sourceEnd(),
				exitFromModule, true, true);
	}

	protected XOTclSourceElementRequestVisitor(
			ISourceElementRequestor requesor, IProblemReporter reporter) {
		super(requesor);
		this.fReporter = reporter;
	}

	public boolean visit(TypeDeclaration s) throws Exception {
		this.fNodes.push(s);

		ISourceElementRequestor.TypeInfo info = new ISourceElementRequestor.TypeInfo();
		info.modifiers = this.getModifiers(s);

		String fullName = s.getName();

		String[] split = s.getName().split("::");
		if (split.length != 0) {
			info.name = split[split.length - 1];
		} else {
			info.name = "";
		}

		info.nameSourceStart = s.getNameStart();
		info.nameSourceEnd = s.getNameEnd();
		info.declarationStart = s.sourceStart();

		ExitFromType exit = this.resolveType(s, fullName + "::dummy", true);

		this.exitStack.push(exit);
		this.fInClass = true;

		return true;
	}

	private int getModifiers(Declaration s) {
		int flags = 0;

		if ((s.getModifiers() & Modifiers.AccAbstract) != 0) {
			flags |= Modifiers.AccAbstract;
		}
		if ((s.getModifiers() & Modifiers.AccNameSpace) != 0
				&& s instanceof TypeDeclaration) {
			return Modifiers.AccNameSpace | flags;
		}
		if ((s.getModifiers() & IXOTclModifiers.AccXOTcl) != 0) {
			// This is ordinary class.
			return IXOTclModifiers.AccXOTcl | flags;
		}
		return flags;
	}

	public boolean endvisit(TypeDeclaration typeDeclaration) throws Exception {
		ExitFromType exit = (ExitFromType) this.exitStack.pop();
		exit.go();
		this.fInClass = false;
		this.onEndVisitClass(typeDeclaration);
		this.fNodes.pop();
		return true;
	}

	private static String[] kw = TclKeywordsManager.getKeywords();
	private static Map kwMap = new HashMap();
	static {
		for (int q = 0; q < kw.length; ++q) {
			kwMap.put(kw[q], Boolean.TRUE);
		}
	}

	public boolean visit(Statement statement) throws Exception {
		this.fNodes.push(statement);
		if (statement instanceof TclPackageDeclaration) {
			this.processPackage(statement);
			this.fNodes.pop();
			return false;
		} else if (statement instanceof TclStatement) {
			this.fNodes.pop();
			processReferences((TclStatement) statement);
			return false;
		} else if (statement instanceof FieldDeclaration) {
			this.processField(statement);
		} else if (statement instanceof XOTclMethodCallStatement) {
			XOTclMethodCallStatement call = (XOTclMethodCallStatement) statement;
			SimpleReference callName = call.getCallName();
			int len = 0;
			if (call.getArgs() != null) {
				ASTListNode arguments = call.getArgs();
				List childs = arguments.getChilds();
				if(childs != null) {
					len = childs.size();
				}
			}

			this.fRequestor.acceptMethodReference(callName.getName()
					.toCharArray(), len, call.sourceStart(), call.sourceEnd());
			
			//Also lets add type references from here.
		}
		return true;
	}

	private void processReferences(TclStatement statement) {
		Expression commandId = statement.getAt(0);
		if (commandId != null && commandId instanceof SimpleReference) {
			String name = ((SimpleReference) commandId).getName();
			if (name.startsWith("::")) {
				name = name.substring(2);
			}
			if (!kwMap.containsKey(name)) {
				int argCount = statement.getCount() - 1;
				if (name.length() > 0) {
					if (name.charAt(0) != '$') {
						this.fRequestor.acceptMethodReference(name
								.toCharArray(), argCount, commandId
								.sourceStart(), commandId.sourceEnd());
					}
				}
			}
		}
		for (int j = 1; j < statement.getCount(); ++j) {
			Expression st = statement.getAt(j);
			if (st instanceof TclExecuteExpression) {
				TclExecuteExpression expr = (TclExecuteExpression) st;
				List exprs = expr.parseExpression();
				for (int i = 0; i < exprs.size(); ++i) {
					if (exprs.get(i) instanceof TclStatement) {
						this.processReferences((TclStatement) exprs.get(i));
					}
				}
			} else if (st instanceof StringLiteral) {
				int pos = 0;
				StringLiteral literal = (StringLiteral) st;
				String value = literal.getValue();
				pos = value.indexOf("$");
				while (pos != -1) {
					SimpleReference ref = TclParseUtils.findVariableFromString(
							literal, pos);
					if (ref != null) {
						this.fRequestor.acceptFieldReference(ref.getName()
								.substring(1).toCharArray(), ref.sourceStart());
						pos = pos + ref.getName().length();
					}
					pos = value.indexOf("$", pos + 1);
				}
			} else if (st instanceof SimpleReference) {
				SimpleReference ref = (SimpleReference) st;
				String name = ref.getName();
				if (name.startsWith("$")) { // This is variable usage.
					this.fRequestor.acceptFieldReference(ref.getName()
							.substring(1).toCharArray(), ref.sourceStart());
				}
			}
		}
	}

	private void processPackage(Statement statement) {
		TclPackageDeclaration pack = (TclPackageDeclaration) statement;
		ASTNode version = pack.getVersion();
		if (pack.getStyle() == TclPackageDeclaration.STYLE_PROVIDE) {
			if (version != null && version instanceof SimpleReference) {
				this.fRequestor.acceptPackage(pack.getNameStart(), pack
						.getNameEnd(), (pack.getName() + " ("
						+ ((SimpleReference) version).getName() + ")")
						.toCharArray());
			} else {
				this.fRequestor.acceptPackage(pack.getNameStart(), pack
						.getNameEnd(), (pack.getName()).toCharArray());
			}
		} else if (pack.getStyle() == TclPackageDeclaration.STYLE_IFNEEDED) {
			if (version != null && version instanceof SimpleReference) {
				this.fRequestor.acceptPackage(pack.getNameStart(), pack
						.getNameEnd(), ("ifneeded " + pack.getName() + " ("
						+ ((SimpleReference) version).getName() + ")")
						.toCharArray());
			} else {
				this.fRequestor.acceptPackage(pack.getNameStart(), pack
						.getNameEnd(), ("ifneeded " + pack.getName())
						.toCharArray());
			}
		}
	}

	private boolean processField(Statement statement) {
		FieldDeclaration decl = (FieldDeclaration) statement;
		ISourceElementRequestor.FieldInfo fi = new ISourceElementRequestor.FieldInfo();
		fi.nameSourceStart = decl.getNameStart();
		fi.nameSourceEnd = decl.getNameEnd() - 1;
		fi.declarationStart = decl.sourceStart();
		fi.modifiers = 0;
		if (statement instanceof TclGlobalVariableDeclaration) {
			fi.modifiers = org.eclipse.dltk.tcl.ast.TclConstants.TCL_FIELD_TYPE_GLOBAL
					| this.getModifiers(decl);
		} else if (statement instanceof TclUpvarVariableDeclaration) {
			fi.modifiers = org.eclipse.dltk.tcl.ast.TclConstants.TCL_FIELD_TYPE_UPVAR
					| this.getModifiers(decl);
		}

		boolean needExit = false;

		String arrayName = null;
		String arrayIndex = null;
		String name = decl.getName();
		if (TclParseUtil.isArrayVariable(name)) {
			arrayName = TclParseUtil.extractArrayName(name);
			arrayIndex = TclParseUtil.extractArrayIndex(name);
		}
		if (arrayName != null) {
			name = arrayName;
		}
		fi.name = name;
		String fullName = TclParseUtil.escapeName(name);
		ExitFromType exit = null;// this.resolveType(decl, fullName, false);
		if ((decl.getModifiers() & IXOTclModifiers.AccXOTcl) != 0
				&& decl instanceof XOTclVariableDeclaration) {
			XOTclFieldDeclaration field = (XOTclFieldDeclaration) decl;
			String tName = field.getDeclaringTypeName();
			if (tName == null) {
				tName = "";
			}
			exit = this.resolveType(field, tName + "::dummy", false);
		} else {
			exit = this.resolveType(decl, fullName, false);
		}
		needExit = this.fRequestor.enterFieldCheckDuplicates(fi);
		int end = decl.sourceEnd();
		if (needExit) {
			if (arrayName != null) {
				ISourceElementRequestor.FieldInfo fiIndex = new ISourceElementRequestor.FieldInfo();
				fiIndex.name = arrayName + "(" + arrayIndex + ")";
				fiIndex.nameSourceStart = decl.getNameStart();
				fiIndex.nameSourceEnd = decl.getNameEnd() - 1;
				fiIndex.declarationStart = decl.sourceStart();
				fiIndex.modifiers = TclConstants.TCL_FIELD_TYPE_INDEX
						| this.getModifiers(decl);
				if (this.fRequestor.enterFieldCheckDuplicates(fiIndex)) {
					this.fRequestor.exitField(end);
				}
			}
			this.fRequestor.exitField(end);
		}
		exit.go();
		return false;
	}

	public boolean visit(ModuleDeclaration declaration) throws Exception {
		this.namespacesLevel.push("::");
		return super.visit(declaration);
	}

	public boolean visit(MethodDeclaration method) throws Exception {
		this.fNodes.push(method);
		String[] parameter = null;
		String[] parameterInitializers = null;
		List arguments = method.getArguments();
		if (arguments != null) {
			parameter = new String[arguments.size()];
			parameterInitializers = new String[arguments.size()];
			for (int a = 0; a < arguments.size(); a++) {
				Object node = arguments.get(a);
				parameterInitializers[a] = null;
				if (node instanceof Argument) {
					Argument ref = (Argument) node;
					parameter[a] = ref.getName();
					Statement e = (Statement) ref.getInitialization();
					if (e != null) {
						if (e instanceof SimpleReference) {
							parameterInitializers[a] = ((SimpleReference) e)
									.getName();
						} else if (e instanceof TclBlockExpression) {
							String name = ((TclBlockExpression) e).getBlock();
							parameterInitializers[a] = TclParseUtil
									.nameFromBlock(name, '{', '}');
						} else if (e instanceof StringLiteral) {
							String name = ((StringLiteral) e).getValue();
							parameterInitializers[a] = TclParseUtil
									.nameFromBlock(name, '"', '"');
						} else if (e instanceof TclExecuteExpression) {
							String name = ((TclBlockExpression) e).getBlock();
							parameterInitializers[a] = name;
						}
					}
					// if( parameterInitializers[a] == null ) {
					// parameterInitializers[a] = "";
					// }
				} else if (node instanceof String) {
					parameter[a] = (String) node;
				}
			}
		}
		ISourceElementRequestor.MethodInfo mi = new ISourceElementRequestor.MethodInfo();
		String sName = method.getName();
		sName = TclParseUtil.escapeName(sName);
		String fullName = sName;

		if (fullName.indexOf("::") != -1) {
			String[] split = fullName.split("::");
			sName = split[split.length - 1];
		}

		mi.parameterNames = parameter;
		mi.parameterInitializers = parameterInitializers;
		mi.name = sName;
		mi.modifiers = this.getModifiers(method);
		mi.nameSourceStart = method.getNameStart();
		mi.nameSourceEnd = method.getNameEnd() - 1;
		mi.declarationStart = method.sourceStart();
		ExitFromType exit = null;
		boolean requireFieldExit = false;
		if ((method.getModifiers() & IXOTclModifiers.AccXOTcl) != 0) {
			String tName = method.getDeclaringTypeName();
			if (tName == null) {
				tName = "";
			}
			exit = this.resolveType(method, tName + "::dummy", false);
			// if( method instanceof XOTclMethodDeclaration) {
			// XOTclMethodDeclaration mDecl = (XOTclMethodDeclaration) method;
			// ASTNode dt = mDecl.getDeclaringXOTclType();
			// if( dt instanceof XOTclInstanceVariable) {
			// XOTclInstanceVariable var = (XOTclInstanceVariable) dt;
			// this.fRequestor.
			// var.getName();
			// }
			// }
		} else {
			exit = this.resolveType(method, fullName, false);
		}
		if (exit.created) {
			if (this.fReporter != null) {
				try {
					this.fReporter.reportProblem(new DefaultProblem("",
							"Namespace not found.", 0, null,
							ProblemSeverities.Warning, method.getNameStart(),
							method.getNameEnd(), -1));
				} catch (CoreException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
		this.fRequestor.enterMethodRemoveSame(mi);
		this.exitStack.push(exit);
		return true;
	}

	public boolean endvisit(MethodDeclaration method) throws Exception {
		super.endvisit(method);
		ExitFromType exit = (ExitFromType) this.exitStack.pop();
		exit.go();
		return true;
	}
}
