package org.eclipse.dltk.tcl.internal.core.codeassist;

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

import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
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.statements.Block;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IParent;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.tcl.ast.TclStatement;
import org.eclipse.dltk.tcl.internal.parser.TclParseUtils;

public class TclResolver {
	private IResolveElementParent resolver;
	private ModuleDeclaration moduleDeclaration;
	private ISourceModule sourceModule;

	public TclResolver(ISourceModule sourceModule,
			ModuleDeclaration moduleDeclaration, IResolveElementParent resolver) {
		this(sourceModule, moduleDeclaration);
		this.resolver = resolver;
	}

	public TclResolver(ISourceModule sourceModule,
			ModuleDeclaration moduleDeclaration) {
		this.sourceModule = sourceModule;
		this.moduleDeclaration = moduleDeclaration;
	}

	public IModelElement findModelElementFrom(ASTNode node) {
		List statements = moduleDeclaration.getStatements();
		List elements = new ArrayList();
		searchAddElementsTo(statements, node, sourceModule, elements);
		if (elements.size() == 1) {
			return (IModelElement) elements.get(0);
		}
		return null;
	}

	public interface IResolveElementParent {
		IModelElement findElementParent(ASTNode node, String name,
				IParent parent);
	}

	public void searchAddElementsTo(List statements, final ASTNode node,
			IParent element, List selectionElements) {
		if (statements == null || element == null) {
			return;
		}
		Iterator i = statements.iterator();
		while (i.hasNext()) {
			ASTNode nde = (ASTNode) i.next();
			if (nde.equals(node)) {
				if (node instanceof MethodDeclaration) {
					String oName = ((MethodDeclaration) node).getName();
					if (oName.indexOf("::") != -1) {
						String pName = oName.substring(0, oName
								.lastIndexOf("::"));
						pName = pName.replaceAll("::", "\\$");

						if (pName.startsWith("$")) {
							if (pName.equals("$")) {
								element = sourceModule;
							} else {
								try {
									element = findTypeFrom(sourceModule
											.getChildren(), "", pName, '$');
								} catch (ModelException e) {
									if (DLTKCore.DEBUG) {
										e.printStackTrace();
									}
								}
							}
						} else {
							pName = "$" + pName;
							try {
								element = findTypeFrom(element.getChildren(),
										"", pName, '$');
								if (element == null) {
									return;
								}
							} catch (ModelException e) {
								e.printStackTrace();
								return;
							}
						}
					}
				}
				String nodeName = getNodeChildName(node);
				if (nodeName != null) {
					IModelElement e = null;
					if (nodeName.startsWith("::")) {
						nodeName = nodeName.substring(2);
						e = findChildrenByName(nodeName, sourceModule);
					} else {
						e = findChildrenByName(nodeName, element);
					}
					if (e == null && resolver != null) {
						e = resolver.findElementParent(node, nodeName, element);
					}
					if (e != null) {
						List toRemove = new ArrayList();
						for (int k = 0; k < selectionElements.size(); ++k) {
							IModelElement ke = (IModelElement) selectionElements
									.get(k);
							String keName = ke.getElementName();
							if (keName.equals(nodeName)) {
								toRemove.add(ke);
							}
						}
						for (int k = 0; k < toRemove.size(); ++k) {
							selectionElements.remove(toRemove.get(k));
						}
						selectionElements.add(e);
					}
				}
				return;
			}
			if (nde.sourceStart() <= node.sourceStart()
					&& node.sourceEnd() <= nde.sourceEnd()) {
				if (element instanceof IParent) {
					if (nde instanceof TypeDeclaration) {
						TypeDeclaration type = (TypeDeclaration) nde;
						String typeName = getNodeChildName(type);
						IModelElement e = findChildrenByName(typeName,
								(IParent) element);
						if (e == null && type.getName().startsWith("::")) {
							try {
								e = (IModelElement) findTypeFrom(sourceModule
										.getChildren(), "", type.getName()
										.replaceAll("::", "\\$"), '$');
							} catch (ModelException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						}
						if (e instanceof IParent) {
							// was: if (e != null || e instanceof IParent)
							List stats = ((TypeDeclaration) nde)
									.getStatements();
							searchAddElementsTo(stats, node, (IParent) e,
									selectionElements);
						}
					} else if (nde instanceof MethodDeclaration) {
						searchInMethod(node, element, nde, selectionElements);
					} /*
					 * else if (nde instanceof TclStatement) { TclStatement s =
					 * (TclStatement) nde; Expression commandId = s.getAt(0);
					 * final IParent e = element; if (commandId != null &&
					 * commandId instanceof SimpleReference) { String qname =
					 * ((SimpleReference) commandId) .getName(); } }
					 */
					else {
						final IParent e = element;
						List statements2 = findExtractBlocks(nde);
						if (statements2.size() > 0) {
							searchAddElementsTo(statements2, node, e,
									selectionElements);
						}
					}
				}
				return;
			}
		}
	}

	public static IModelElement findChildrenByName(String childName,
			IParent element) {
		try {
			if (element == null) {
				return null;
			}
			String nextName = null;
			int pos;
			if ((pos = childName.indexOf("::")) != -1) {
				nextName = childName.substring(pos + 2);
				// childName = "";
				String[] split = childName.split("::");
				if (split.length > 0) {
					childName = split[0];
				}
			}
			IModelElement[] children = element.getChildren();
			if (children != null) {
				for (int i = 0; i < children.length; ++i) {
					String name = children[i].getElementName();
					if (children[i] instanceof IField
							&& name.indexOf('(') != -1) {
						name = name.substring(0, name.indexOf('('));
					}
					if (name.equals(childName)) {
						if (nextName == null) {
							return children[i];
						} else if (children[i] instanceof IParent) {
							return findChildrenByName(nextName,
									(IParent) children[i]);
						}
					}
				}
			}
		} catch (ModelException e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static IParent findTypeFrom(IModelElement[] childs, String name,
			String parentName, char delimiter) {
		try {
			for (int i = 0; i < childs.length; ++i) {
				if (childs[i] instanceof IType) {
					// if ((((IType) childs[i]).getFlags() &
					// Modifiers.AccNameSpace) == 0) {
					// continue;
					// }
					IType type = (IType) childs[i];
					String qname = name + delimiter + type.getElementName();
					if (qname.equals(parentName)) {
						return type;
					}
					IParent val = findTypeFrom(type.getChildren(), qname,
							parentName, delimiter);
					if (val != null) {
						return val;
					}
				}
			}
		} catch (ModelException e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static String getNodeChildName(ASTNode node) {
		if (node instanceof MethodDeclaration) {
			MethodDeclaration method = (MethodDeclaration) node;
			String name = method.getName();
			if (name.indexOf("::") != -1) {
				return name.substring(name.lastIndexOf("::") + 2);
			}
			return name;
		} else if (node instanceof TypeDeclaration) {
			TypeDeclaration type = (TypeDeclaration) node;
			String name = type.getName();
			/*
			 * if (name.startsWith("::")) { return name.substring(2); }
			 */
			return name;
		} else if (node instanceof TclStatement) {
			String[] var = TclParseUtils.returnVariable((TclStatement) node);
			if (var != null) {
				return var[0];
			}
		} else if (node instanceof FieldDeclaration) {
			return ((FieldDeclaration) node).getName();
		}
		return null;
	}

	public void searchInMethod(final ASTNode node, IParent element,
			ASTNode nde, List selectionElements) {
		MethodDeclaration method = (MethodDeclaration) nde;
		String methodName = method.getName();
		if (methodName.indexOf("::") != -1) {
			String pName = methodName
					.substring(0, methodName.lastIndexOf("::"));
			pName = pName.replaceAll("::", "\\$");
			if (pName.equals("$")) {
				element = sourceModule;
			} else {
				try {
					element = TclResolver.findTypeFrom(sourceModule
							.getChildren(), "", pName, '$');
					if (element == null) {
						return;
					}
				} catch (ModelException e) {
					e.printStackTrace();
					return;
				}
			}
			methodName = TclResolver.getNodeChildName(nde);
		} else {
			if (method.getDeclaringTypeName() != null) {
				String pName = method.getDeclaringTypeName();
				if (!pName.startsWith("::")) {
					pName = "$" + pName;
				}
				pName = pName.replaceAll("::", "\\$");
				if (pName.equals("$")) {
					element = sourceModule;
				} else {
					try {
						element = TclResolver.findTypeFrom(sourceModule
								.getChildren(), "", pName, '$');
						if (element == null) {
							return;
						}
					} catch (ModelException e) {
						e.printStackTrace();
						return;
					}
				}
				methodName = TclResolver.getNodeChildName(nde);
			}
		}
		IModelElement e = TclResolver.findChildrenByName(methodName,
				(IParent) element);
		if (e != null && e instanceof IParent) {
			List stats = ((MethodDeclaration) nde).getStatements();
			searchAddElementsTo(stats, node, (IParent) e, selectionElements);
		}
	}

	public static List findExtractBlocks(ASTNode node) {
		final List statements2 = new ArrayList();
		ASTVisitor visitor = new ASTVisitor() {
			public boolean visit(Expression s) throws Exception {
				if (s instanceof Block) {
					statements2.addAll(((Block) s).getStatements());
				}
				return super.visit(s);
			}
		};
		try {
			node.traverse(visitor);
		} catch (Exception e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
		}
		return statements2;
	}
}
