/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 
 *******************************************************************************/
package org.eclipse.dltk.ruby.internal.parser.mixin;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.core.runtime.Assert;
import org.eclipse.dltk.ast.ASTListNode;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.Modifiers;
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.CallExpression;
import org.eclipse.dltk.ast.references.ConstantReference;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.references.VariableReference;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.mixin.IMixinRequestor;
import org.eclipse.dltk.core.mixin.MixinModel;
import org.eclipse.dltk.core.mixin.IMixinRequestor.ElementInfo;
import org.eclipse.dltk.internal.core.ModelElement;
import org.eclipse.dltk.ruby.ast.RubyAliasExpression;
import org.eclipse.dltk.ruby.ast.RubyAssignment;
import org.eclipse.dltk.ruby.ast.RubyCallArgument;
import org.eclipse.dltk.ruby.ast.RubyClassDeclaration;
import org.eclipse.dltk.ruby.ast.RubyColonExpression;
import org.eclipse.dltk.ruby.ast.RubyConstantDeclaration;
import org.eclipse.dltk.ruby.ast.RubyMethodArgument;
import org.eclipse.dltk.ruby.ast.RubySelfReference;
import org.eclipse.dltk.ruby.ast.RubySingletonClassDeclaration;
import org.eclipse.dltk.ruby.ast.RubySingletonMethodDeclaration;
import org.eclipse.dltk.ruby.core.model.FakeField;
import org.eclipse.dltk.ruby.core.model.FakeMethod;
import org.eclipse.dltk.ruby.internal.parser.visitors.RubyAttributeHandler;

public class RubyMixinBuildVisitor extends ASTVisitor {

	private static final String INSTANCE_SUFFIX = RubyMixin.INSTANCE_SUFFIX;
	private static final String VIRTUAL_SUFFIX = RubyMixin.VIRTUAL_SUFFIX;
	private static final String SEPARATOR = MixinModel.SEPARATOR;

	private final ISourceModule sourceModule;
	private final boolean moduleAvailable;
	private final IMixinRequestor requestor;
	private final HashSet allReportedKeys = new HashSet();

	private abstract class Scope {
		private final ASTNode node;

		public Scope(ASTNode node) {
			super();
			this.node = node;
		}

		public ASTNode getNode() {
			return node;
		}

		public abstract String reportMethod(String name, IMethod object);

		public abstract String reportVariable(String name, IField object);

		public abstract String reportType(String name, IType object,
				boolean module);

		public abstract String reportInclude(String object);

		public abstract String reportExtend(String object);

		public abstract String getClassKey();

		public abstract String getKey();
	}

	private class SourceModuleScope extends Scope {

		public SourceModuleScope(ModuleDeclaration node) {
			super(node);
		}

		public String getClassKey() {
			return "Object"; //$NON-NLS-1$
		}

		public String reportMethod(String name, IMethod object) {
			return report(name, RubyMixinElementInfo.createMethod(object));
		}

		public String reportType(String name, IType object, boolean module) {
			RubyMixinElementInfo obj = null;
			if (module)
				obj = RubyMixinElementInfo.createModule(object);
			else
				obj = RubyMixinElementInfo.createClass(object);
			report(name + INSTANCE_SUFFIX, obj);
			return report(name, obj);
		}

		public String reportVariable(String name, IField object) {
			RubyMixinElementInfo info = (name.endsWith(VIRTUAL_SUFFIX)) ? RubyMixinElementInfo
					.createVirtualClass()
					: RubyMixinElementInfo.createVariable(object);
			if (name.startsWith("$")) //$NON-NLS-1$
				return report(name, info);
			if (name.startsWith("@") || Character.isUpperCase(name.charAt(0))) //$NON-NLS-1$
				return report("Object" + SEPARATOR + name, info); //$NON-NLS-1$
			else {
				if (info.getKind() == RubyMixinElementInfo.K_VIRTUAL)
					return report(name, info);
				return name; // no top-level vars
			}
		}

		public String getKey() {
			return "Object"; //$NON-NLS-1$
		}

		public String reportInclude(String object) {
			return null;
		}

		public String reportExtend(String object) {
			return null;
		}

	}

	private class ClassScope extends Scope {

		private final String classKey;

		public ClassScope(ASTNode node, String classKey) {
			super(node);
			this.classKey = classKey;
		}

		public String reportMethod(String name, IMethod object) {
			String key = classKey + INSTANCE_SUFFIX + SEPARATOR + name;
			return report(key, RubyMixinElementInfo.createMethod(object));
		}

		public String reportType(String name, IType obj, boolean module) {
			RubyMixinElementInfo object = null;
			if (module)
				object = RubyMixinElementInfo.createModule(obj);
			else
				object = RubyMixinElementInfo.createClass(obj);
			String key = classKey + SEPARATOR + name;
			report(key + INSTANCE_SUFFIX, object);
			return report(key, object);
		}

		public String reportVariable(String name, IField object) {
			RubyMixinElementInfo info = (name.endsWith(VIRTUAL_SUFFIX)) ? RubyMixinElementInfo
					.createVirtualClass()
					: RubyMixinElementInfo.createVariable(object);
			if (name.startsWith("$")) //$NON-NLS-1$
				return report(name, info);
			RubyMixinElementInfo obj = info;
			String key = null;
			if (name.startsWith("@@")) { //$NON-NLS-1$
				key = classKey + SEPARATOR + name;
				report(classKey + INSTANCE_SUFFIX + SEPARATOR + name, obj);
				return report(key, obj);
			} else if (name.startsWith("@")) { //$NON-NLS-1$
				key = classKey + SEPARATOR + name;
				return report(key, obj);
			} else {
				key = classKey + SEPARATOR + name;
				return report(key, obj);
			}
		}

		public String getClassKey() {
			return classKey;
		}

		public String getKey() {
			return classKey;
		}

		public String reportInclude(String object) {
			return report(classKey + INSTANCE_SUFFIX, new RubyMixinElementInfo(
					RubyMixinElementInfo.K_INCLUDE, object));
		}

		public String reportExtend(String object) {
			return report(classKey + INSTANCE_SUFFIX, new RubyMixinElementInfo(
					RubyMixinElementInfo.K_EXTEND, object));
		}

	}

	private class MetaClassScope extends Scope {

		private final String classKey;

		public MetaClassScope(ASTNode node, String classKey) {
			super(node);
			this.classKey = classKey;
		}

		public String reportMethod(String name, IMethod object) {
			return report(classKey + SEPARATOR + name, RubyMixinElementInfo
					.createMethod(object));
		}

		public String reportType(String name, IType object, boolean module) {
			RubyMixinElementInfo obj = null;
			if (module)
				obj = RubyMixinElementInfo.createModule(object);
			else
				obj = RubyMixinElementInfo.createClass(object);
			report(classKey + SEPARATOR + name + INSTANCE_SUFFIX, obj);
			return report(classKey + SEPARATOR + name, obj);
		}

		public String reportVariable(String name, IField object) {
			RubyMixinElementInfo info = (name.endsWith(VIRTUAL_SUFFIX)) ? RubyMixinElementInfo
					.createVirtualClass()
					: RubyMixinElementInfo.createVariable(object);
			if (name.startsWith("$")) //$NON-NLS-1$
				return report(name, info);
			RubyMixinElementInfo obj = info;
			if (name.startsWith("@@")) { //$NON-NLS-1$
				report(classKey + INSTANCE_SUFFIX + SEPARATOR + name, obj);
				return report(classKey + SEPARATOR + name, obj);
			} else {
				return report(classKey + SEPARATOR + name, obj);
			}
		}

		public String getClassKey() {
			return classKey;
		}

		public String getKey() {
			return classKey;
		}

		public String reportInclude(String object) {
			return report(classKey, new RubyMixinElementInfo(
					RubyMixinElementInfo.K_INCLUDE, object));
		}

		public String reportExtend(String object) {
			return report(classKey, new RubyMixinElementInfo(
					RubyMixinElementInfo.K_EXTEND, object));
		}

	}

	private class MethodScope extends Scope {

		private final Scope classScope;
		private final String methodKey;

		public MethodScope(ASTNode node, Scope classScope, String methodKey) {
			super(node);
			this.classScope = classScope;
			this.methodKey = methodKey;
		}

		public String reportMethod(String name, IMethod object) {
			return classScope.reportMethod(name, object);
		}

		public String reportType(String name, IType obj, boolean module) {
			// throw new RuntimeException();
			return null;
		}

		public String reportVariable(String name, IField obj) {
			RubyMixinElementInfo info = (name.endsWith(VIRTUAL_SUFFIX)) ? RubyMixinElementInfo
					.createVirtualClass()
					: RubyMixinElementInfo.createVariable(obj);
			if (name.startsWith("$")) //$NON-NLS-1$
				return report(name, info);
			RubyMixinElementInfo object = info;
			if (name.startsWith("@@")) { //$NON-NLS-1$
				String key = classScope.getKey() + SEPARATOR + name;
				report(
						classScope.getKey() + INSTANCE_SUFFIX + SEPARATOR
								+ name, object);
				return report(key, object);
			}
			if (name.startsWith("@")) { //$NON-NLS-1$
				String key;
				if (classScope instanceof ClassScope) {
					key = classScope.getKey() + INSTANCE_SUFFIX + SEPARATOR
							+ name;
				} else {
					key = classScope.getKey() + SEPARATOR + name;
				}
				return report(key, object);
			} else {
				return report(methodKey + SEPARATOR + name, object);
			}
		}

		public String getClassKey() {
			return classScope.getClassKey();
		}

		public String getKey() {
			return methodKey;
		}

		public String reportInclude(String object) {
			return classScope.reportInclude(object);
		}

		public String reportExtend(String object) {
			return classScope.reportExtend(object);
		}

	}

	private Stack scopes = new Stack();
	private final ModuleDeclaration module;

	public RubyMixinBuildVisitor(ModuleDeclaration module,
			ISourceModule sourceModule, boolean moduleAvailable,
			IMixinRequestor requestor) {
		super();
		this.module = module;
		this.sourceModule = sourceModule;
		this.moduleAvailable = moduleAvailable;
		this.requestor = requestor;
	}

	private Scope peekScope() {
		return (Scope) scopes.peek();
	}

	public boolean visit(ModuleDeclaration s) throws Exception {
		this.scopes.add(new SourceModuleScope(s));
		return true;
	}

	public boolean visit(MethodDeclaration decl) throws Exception {
		IMethod obj = null;
		String name = decl.getName();
		if (moduleAvailable) {
			IModelElement element = findModelElementFor(decl);
			if (element instanceof IMethod) {
				obj = (IMethod) element;
			} else {
				return false;
			}
		}
		if (decl instanceof RubySingletonMethodDeclaration) {
			RubySingletonMethodDeclaration singl = (RubySingletonMethodDeclaration) decl;
			ASTNode receiver = singl.getReceiver();
			if (receiver instanceof RubySelfReference) {
				Scope scope = peekScope();
				MetaClassScope metaScope = new MetaClassScope(scope.getNode(),
						scope.getClassKey());
				String method = metaScope.reportMethod(name, obj);
				scopes.push(new MethodScope(decl, metaScope, method));
			} else if (receiver instanceof ConstantReference
					|| receiver instanceof RubyColonExpression) {
				String evaluatedClassKey = evaluateClassKey(receiver);
				if (evaluatedClassKey != null) {
					MetaClassScope metaScope = new MetaClassScope(decl,
							evaluatedClassKey);
					String method = metaScope.reportMethod(name, obj);
					scopes.push(new MethodScope(decl, metaScope, method));
				}
			} else {
				// TODO
			}
		} else {
			Scope scope = peekScope();
			String method = scope.reportMethod(name, obj);
			scopes.push(new MethodScope(decl, scope, method));
		}
		return true;
	}

	private IModelElement findModelElementFor(ASTNode decl)
			throws ModelException {
		// return null;
		return sourceModule.getElementAt(decl.sourceStart() + 1);
	}

	public boolean visitGeneral(ASTNode s) throws Exception {
		if (s instanceof RubyMethodArgument) {
			RubyMethodArgument argument = (RubyMethodArgument) s;
			String name = argument.getName();
			Scope scope = peekScope();
			IField obj = null;
			if (sourceModule != null) {
				obj = new FakeField((ModelElement) sourceModule, name, s
						.sourceStart(), s.sourceEnd() - s.sourceStart());
			}
			scope.reportVariable(name, obj);
		} else if (s instanceof RubyAssignment) {
			RubyAssignment assignment = (RubyAssignment) s;
			ASTNode left = assignment.getLeft();
			if (left instanceof VariableReference) {
				VariableReference ref = (VariableReference) left;
				String name = ref.getName();
				Scope scope = peekScope();
				IField obj = null;
				if (sourceModule != null)
					obj = new FakeField((ModelElement) sourceModule, name, ref
							.sourceStart(), ref.sourceEnd() - ref.sourceStart());
				scope.reportVariable(name, obj);
			}
		} else if (s instanceof CallExpression) {
			visit((CallExpression) s);
		} else if (s instanceof RubyConstantDeclaration) {
			RubyConstantDeclaration constantDeclaration = (RubyConstantDeclaration) s;
			SimpleReference name2 = constantDeclaration.getName();
			String name = name2.getName();
			boolean closeScope = false;
			if (constantDeclaration.getPath() instanceof RubyColonExpression) {
				RubyColonExpression colon = (RubyColonExpression) constantDeclaration
						.getPath();
				String classKey = evaluateClassKey(colon.getLeft());
				if (classKey != null) {
					this.scopes.add(new ClassScope(colon, classKey));
					closeScope = true;
				}
			}
			Scope scope = peekScope();
			IField obj = null;
			if (sourceModule != null)
				obj = new FakeField((ModelElement) sourceModule, name, name2
						.sourceStart(), name2.sourceEnd() - name2.sourceStart());
			scope.reportVariable(name, obj);
			if (closeScope)
				this.scopes.pop();
		} else if (s instanceof RubyAliasExpression) {
			RubyAliasExpression alias = (RubyAliasExpression) s;
			String oldValue = alias.getOldValue();
			if (!oldValue.startsWith("$")) { //$NON-NLS-1$
				String newValue = alias.getNewValue();
				String nkey = peekScope().reportMethod(newValue, null);
				report(nkey, new RubyMixinElementInfo(
						RubyMixinElementInfo.K_ALIAS, alias));
			}
		}
		return true;
	}

	public boolean visit(CallExpression call) throws Exception {
		if (call.getReceiver() == null
				&& call.getName().equals("include") && call.getArgs().getChilds().size() > 0) { //$NON-NLS-1$
			ASTNode expr = (ASTNode) call.getArgs().getChilds().get(0);
			if (expr instanceof RubyCallArgument)
				expr = ((RubyCallArgument) expr).getValue();
			Scope scope = peekScope();
			String incl = evaluateClassKey(expr);
			if (incl != null)
				scope.reportInclude(incl);
			return false;
		} else if (call.getReceiver() == null
				&& call.getName().equals("extend") //$NON-NLS-1$
				&& call.getArgs().getChilds().size() > 0) {
			ASTNode expr = (ASTNode) call.getArgs().getChilds().get(0);
			if (expr instanceof RubyCallArgument)
				expr = ((RubyCallArgument) expr).getValue();
			scopes.push(new MetaClassScope(call, peekScope().getClassKey()));
			Scope scope = peekScope();
			String ext = evaluateClassKey(expr);
			if (ext != null)
				scope.reportExtend(ext);
			scopes.pop();
			return false;
		} else if (RubyAttributeHandler.isAttributeCreationCall(call)
				&& sourceModule != null) {
			Scope scope = peekScope();
			RubyAttributeHandler info = new RubyAttributeHandler(call);
			List readers = info.getReaders();
			for (Iterator iterator = readers.iterator(); iterator.hasNext();) {
				ASTNode n = (ASTNode) iterator.next();
				String attr = RubyAttributeHandler.getText(n);
				if (attr == null)
					continue;
				FakeMethod fakeMethod = new FakeMethod(
						(ModelElement) sourceModule, attr, n.sourceStart(),
						attr.length(), n.sourceStart(), attr.length());
				fakeMethod.setFlags(Modifiers.AccPublic);
				scope.reportMethod(attr, fakeMethod);
			}
			List writers = info.getWriters();
			for (Iterator iterator = writers.iterator(); iterator.hasNext();) {
				ASTNode n = (ASTNode) iterator.next();
				String attr = RubyAttributeHandler.getText(n);
				if (attr == null)
					continue;
				FakeMethod fakeMethod = new FakeMethod(
						(ModelElement) sourceModule, attr + "=", n //$NON-NLS-1$
								.sourceStart(), attr.length(), n.sourceStart(),
						attr.length());
				fakeMethod.setFlags(Modifiers.AccPublic);
				fakeMethod.setParameters(new String[] { attr });
				scope.reportMethod(attr + "=", fakeMethod); //$NON-NLS-1$
			}
			return false;
		}
		return true;
	}

	public boolean visit(TypeDeclaration decl) throws Exception {
		IType obj = null;
		if (moduleAvailable) {
			IModelElement elementFor = findModelElementFor(decl);
			if (!(elementFor instanceof IType)) {
				elementFor = findModelElementFor(decl);
			}
			obj = (IType) elementFor;
		}
		boolean module = (decl.getModifiers() & Modifiers.AccModule) != 0;
		if (decl instanceof RubySingletonClassDeclaration) {
			RubySingletonClassDeclaration declaration = (RubySingletonClassDeclaration) decl;
			ASTNode receiver = declaration.getReceiver();
			if (receiver instanceof RubySelfReference) {
				Scope scope = peekScope();
				scopes.push(new MetaClassScope(decl, scope.getClassKey()));
				return true;
			} else if (receiver instanceof ConstantReference
					|| receiver instanceof RubyColonExpression) {
				String evaluatedClassKey = evaluateClassKey(receiver);
				if (evaluatedClassKey != null) {
					MetaClassScope metaScope = new MetaClassScope(decl,
							evaluatedClassKey);
					scopes.push(metaScope);
					return true;
				}
			} else if (receiver instanceof VariableReference) {
				VariableReference ref = (VariableReference) receiver;
				Scope scope = peekScope();
				String key = scope.reportVariable(ref.getName(), null);
				if (key != null) {
					key += VIRTUAL_SUFFIX;
					report(key, new RubyMixinElementInfo(
							RubyMixinElementInfo.K_VIRTUAL, obj));
					scopes.push(new MetaClassScope(decl, key));
					return true;
				}
			} else {
				// TODO: add common method for singletons resolving
			}
		} else if (decl instanceof RubyClassDeclaration) {
			RubyClassDeclaration declaration = (RubyClassDeclaration) decl;
			ASTNode className = declaration.getClassName();
			if (className instanceof ConstantReference) {
				String name = ((ConstantReference) className).getName();
				Scope scope = peekScope();
				String newKey = scope.reportType(name, obj, module);
				scopes.push(new ClassScope(decl, newKey));
			} else {
				String name = evaluateClassKey(className);
				if (name != null) {
					report(name, RubyMixinElementInfo.createClass(obj));
					scopes.push(new ClassScope(decl, name));
				}
			}
			ASTListNode superClasses = declaration.getSuperClasses();
			if (superClasses != null && superClasses.getChilds().size() == 1) {
				ASTNode s = (ASTNode) superClasses.getChilds().get(0);
				// if (this.sourceModule != null) {
				SuperclassReferenceInfo ref = new SuperclassReferenceInfo(s,
						this.module, sourceModule);
				Scope scope = peekScope();
				report(scope.getKey() + INSTANCE_SUFFIX,
						new RubyMixinElementInfo(RubyMixinElementInfo.K_SUPER,
								ref));
				report(scope.getKey(), new RubyMixinElementInfo(
						RubyMixinElementInfo.K_SUPER, ref));
				// }
			}
			return true;
		} else {
			String name = decl.getName();
			Scope scope = peekScope();
			String newKey = scope.reportType(name, obj, module);
			scopes.push(new ClassScope(decl, newKey));
			return true;
		}
		return false;
	}

	private String report(String key, RubyMixinElementInfo object) {
		RubyMixinModel.getRawInstance().clearKeysCashe(key);
		ElementInfo info = new IMixinRequestor.ElementInfo();
		info.key = key;
		info.object = object;
		if (requestor != null) {
			requestor.reportElement(info);
			// System.out.println("Mixin reported: " + key);
		}
		allReportedKeys.add(key);
		return key;
	}

	private String evaluateClassKey(ASTNode expr) {
		if (expr instanceof RubyColonExpression) {
			RubyColonExpression colonExpression = (RubyColonExpression) expr;
			if (colonExpression.isFull()) {
				return colonExpression.getName();
			} else {
				String key = evaluateClassKey(colonExpression.getLeft());
				if (key != null) {
					return key + SEPARATOR + colonExpression.getName();
				}
			}
		} else if (expr instanceof ConstantReference) {
			ConstantReference constantReference = (ConstantReference) expr;
			// simple heuristic
			int size = this.scopes.size();
			for (int i = size - 1; i >= 0; i--) {
				String possibleKey = ""; //$NON-NLS-1$
				if (i > 0) {
					Scope s = (Scope) this.scopes.get(i);
					possibleKey = s.getKey() + SEPARATOR
							+ constantReference.getName();
				} else
					possibleKey = constantReference.getName();
				if (this.allReportedKeys.contains(possibleKey))
					return possibleKey;
			}

			return constantReference.getName();
		}
		return null;
	}

	public void endvisitGeneral(ASTNode node) throws Exception {
		Scope scope = (Scope) scopes.peek();
		if (scope.getNode() == node) {
			scopes.pop();
		}
		super.endvisitGeneral(node);
	}

	public static String[] restoreScopesByNodes(ASTNode[] nodes) {
		Assert.isLegal(nodes != null);
		Assert.isLegal(nodes.length > 0);
		String[] keys = new String[nodes.length];
		RubyMixinBuildVisitor visitor = new RubyMixinBuildVisitor(
				(ModuleDeclaration) nodes[0], null, false, null);
		for (int i = 0; i < nodes.length; i++) {
			try {
				if (nodes[i] instanceof ModuleDeclaration) {
					visitor.visit((ModuleDeclaration) nodes[i]);
				} else if (nodes[i] instanceof TypeDeclaration) {
					visitor.visit((TypeDeclaration) nodes[i]);
				} else if (nodes[i] instanceof MethodDeclaration) {
					visitor.visit((MethodDeclaration) nodes[i]);
				} else {
					visitor.visit(nodes[i]);
				}
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
			Scope scope = visitor.peekScope();
			keys[i] = scope.getKey();
		}
		return keys;
	}

}
