/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * 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
 *
 * Contributors:
 *     PARC                     initial implementation
 *     Alexandre Vasseur        support for @AJ style
 * ******************************************************************/

package org.aspectj.ajdt.internal.core.builder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.InterTypeConstructorDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.InterTypeDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.InterTypeFieldDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.InterTypeMethodDeclaration;
import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
import org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment;
import org.aspectj.asm.IProgramElement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.model.AsmRelationshipUtils;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.DeclarePrecedence;
import org.aspectj.weaver.patterns.DeclareSoft;
import org.aspectj.weaver.patterns.TypePattern;
import org.aspectj.weaver.patterns.TypePatternList;

/**
 * @author Mik Kersten
 */
public class AsmElementFormatter {

	public void genLabelAndKind(MethodDeclaration methodDeclaration, IProgramElement node) {

		if (methodDeclaration instanceof AdviceDeclaration) {
			AdviceDeclaration ad = (AdviceDeclaration) methodDeclaration;
			node.setKind(IProgramElement.Kind.ADVICE);

			if (ad.kind == AdviceKind.Around) {
				node.setCorrespondingType(ad.returnType.toString()); // returnTypeToString(0));
			}

			StringBuffer details = new StringBuffer();
			if (ad.pointcutDesignator != null) {
				details.append(AsmRelationshipUtils.genPointcutDetails(ad.pointcutDesignator.getPointcut()));
			} else {
				details.append(AsmRelationshipUtils.POINTCUT_ABSTRACT);
			}
			node.setName(ad.kind.toString());
			// if (details.length()!=0)
			node.setDetails(details.toString());
			setParameters(methodDeclaration, node);

		} else if (methodDeclaration instanceof PointcutDeclaration) {
			// PointcutDeclaration pd = (PointcutDeclaration) methodDeclaration;
			node.setKind(IProgramElement.Kind.POINTCUT);
			node.setName(translatePointcutName(new String(methodDeclaration.selector)));
			setParameters(methodDeclaration, node);

		} else if (methodDeclaration instanceof DeclareDeclaration) {
			DeclareDeclaration declare = (DeclareDeclaration) methodDeclaration;
			String name = AsmRelationshipUtils.DEC_LABEL + " ";
			if (declare.declareDecl instanceof DeclareErrorOrWarning) {
				DeclareErrorOrWarning deow = (DeclareErrorOrWarning) declare.declareDecl;

				if (deow.isError()) {
					node.setKind(IProgramElement.Kind.DECLARE_ERROR);
					name += AsmRelationshipUtils.DECLARE_ERROR;
				} else {
					node.setKind(IProgramElement.Kind.DECLARE_WARNING);
					name += AsmRelationshipUtils.DECLARE_WARNING;
				}
				node.setName(name);
				node.setDetails("\"" + AsmRelationshipUtils.genDeclareMessage(deow.getMessage()) + "\"");

			} else if (declare.declareDecl instanceof DeclareParents) {

				node.setKind(IProgramElement.Kind.DECLARE_PARENTS);
				DeclareParents dp = (DeclareParents) declare.declareDecl;
				node.setName(name + AsmRelationshipUtils.DECLARE_PARENTS);

				String kindOfDP = null;
				StringBuffer details = new StringBuffer("");
				TypePattern[] newParents = dp.getParents().getTypePatterns();
				for (int i = 0; i < newParents.length; i++) {
					TypePattern tp = newParents[i];
					UnresolvedType tx = tp.getExactType();
					if (kindOfDP == null) {
						kindOfDP = "implements ";
						try {
							ResolvedType rtx = tx.resolve(((AjLookupEnvironment) declare.scope.environment()).factory.getWorld());
							if (!rtx.isInterface()) {
								kindOfDP = "extends ";
							}
						} catch (Throwable t) {
							// What can go wrong???? who knows!
						}

					}
					String typename = tp.toString();
					if (typename.lastIndexOf(".") != -1) {
						typename = typename.substring(typename.lastIndexOf(".") + 1);
					}
					details.append(typename);
					if ((i + 1) < newParents.length) {
						details.append(",");
					}
				}
				node.setDetails(kindOfDP + details.toString());

			} else if (declare.declareDecl instanceof DeclareSoft) {
				node.setKind(IProgramElement.Kind.DECLARE_SOFT);
				DeclareSoft ds = (DeclareSoft) declare.declareDecl;
				node.setName(name + AsmRelationshipUtils.DECLARE_SOFT);
				node.setDetails(genTypePatternLabel(ds.getException()));

			} else if (declare.declareDecl instanceof DeclarePrecedence) {
				node.setKind(IProgramElement.Kind.DECLARE_PRECEDENCE);
				DeclarePrecedence ds = (DeclarePrecedence) declare.declareDecl;
				node.setName(name + AsmRelationshipUtils.DECLARE_PRECEDENCE);
				node.setDetails(genPrecedenceListLabel(ds.getPatterns()));

			} else if (declare.declareDecl instanceof DeclareAnnotation) {
				DeclareAnnotation deca = (DeclareAnnotation) declare.declareDecl;
				String thekind = deca.getKind().toString();
				node.setName(name + "@" + thekind.substring(3));

				if (deca.getKind() == DeclareAnnotation.AT_CONSTRUCTOR) {
					node.setKind(IProgramElement.Kind.DECLARE_ANNOTATION_AT_CONSTRUCTOR);
				} else if (deca.getKind() == DeclareAnnotation.AT_FIELD) {
					node.setKind(IProgramElement.Kind.DECLARE_ANNOTATION_AT_FIELD);
				} else if (deca.getKind() == DeclareAnnotation.AT_METHOD) {
					node.setKind(IProgramElement.Kind.DECLARE_ANNOTATION_AT_METHOD);
				} else if (deca.getKind() == DeclareAnnotation.AT_TYPE) {
					node.setKind(IProgramElement.Kind.DECLARE_ANNOTATION_AT_TYPE);
				}
				node.setDetails(genDecaLabel(deca));

			} else {
				node.setKind(IProgramElement.Kind.ERROR);
				node.setName(AsmRelationshipUtils.DECLARE_UNKNONWN);
			}

		} else if (methodDeclaration instanceof InterTypeDeclaration) {
			InterTypeDeclaration itd = (InterTypeDeclaration) methodDeclaration;
			String fqname = itd.getOnType().toString();
			if (fqname.indexOf(".") != -1) {
				// TODO the string handling round here is embarrassing
				node.addFullyQualifiedName(fqname + "." + new String(itd.getDeclaredSelector()));
				fqname = fqname.substring(fqname.lastIndexOf(".") + 1);
			}
			String name = fqname + "." + new String(itd.getDeclaredSelector());
			if (methodDeclaration instanceof InterTypeFieldDeclaration) {
				node.setKind(IProgramElement.Kind.INTER_TYPE_FIELD);
				node.setName(name);
			} else if (methodDeclaration instanceof InterTypeMethodDeclaration) {
				node.setKind(IProgramElement.Kind.INTER_TYPE_METHOD);
				node.setName(name);
			} else if (methodDeclaration instanceof InterTypeConstructorDeclaration) {
				node.setKind(IProgramElement.Kind.INTER_TYPE_CONSTRUCTOR);

				// StringBuffer argumentsSignature = new StringBuffer("fubar");
				// argumentsSignature.append("(");
				// if (methodDeclaration.arguments!=null && methodDeclaration.arguments.length>1) {
				//
				// for (int i = 1;i<methodDeclaration.arguments.length;i++) {
				// argumentsSignature.append(methodDeclaration.arguments[i]);
				// if (i+1<methodDeclaration.arguments.length) argumentsSignature.append(",");
				// }
				// }
				// argumentsSignature.append(")");
				// InterTypeConstructorDeclaration itcd = (InterTypeConstructorDeclaration)methodDeclaration;
				node.setName(itd.getOnType().toString() + "." + itd.getOnType().toString().replace('.', '_'));
			} else {
				node.setKind(IProgramElement.Kind.ERROR);
				node.setName(name);
			}
			node.setCorrespondingType(new String(itd.returnType.resolvedType.readableName()));
			if (node.getKind() != IProgramElement.Kind.INTER_TYPE_FIELD) {
				setParameters(methodDeclaration, node);
			}
		} else {
			if (methodDeclaration.isConstructor()) {
				node.setKind(IProgramElement.Kind.CONSTRUCTOR);
			} else {
				node.setKind(IProgramElement.Kind.METHOD);

				// TODO AV - could speed up if we could dig only for @Aspect declaring types (or aspect if mixed style allowed)
				// ??? how to : node.getParent().getKind().equals(IProgramElement.Kind.ASPECT)) {
				if (true && methodDeclaration != null && methodDeclaration.annotations != null && methodDeclaration.scope != null) {
					for (int i = 0; i < methodDeclaration.annotations.length; i++) {
						// Note: AV: implicit single advice type support here (should be enforced somewhere as well (APT etc))
						Annotation annotation = methodDeclaration.annotations[i];
						String annotationSig = new String(annotation.type.getTypeBindingPublic(methodDeclaration.scope).signature());
						if (annotationSig.charAt(1) == 'o') {
							if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(annotationSig)) {
								node.setKind(IProgramElement.Kind.POINTCUT);
								node.setAnnotationStyleDeclaration(true); // pointcuts don't seem to get handled quite right...
								break;
							} else if ("Lorg/aspectj/lang/annotation/Before;".equals(annotationSig)
									|| "Lorg/aspectj/lang/annotation/After;".equals(annotationSig)
									|| "Lorg/aspectj/lang/annotation/AfterReturning;".equals(annotationSig)
									|| "Lorg/aspectj/lang/annotation/AfterThrowing;".equals(annotationSig)
									|| "Lorg/aspectj/lang/annotation/Around;".equals(annotationSig)) {
								node.setKind(IProgramElement.Kind.ADVICE);
								node.setAnnotationStyleDeclaration(true);
								// TODO AV - all are considered anonymous - is that ok?
								node.setDetails(AsmRelationshipUtils.POINTCUT_ANONYMOUS);
								break;
							}
						}
					}
				}
			}
			node.setName(new String(methodDeclaration.selector));
			setParameters(methodDeclaration, node);
		}
	}

	private String genDecaLabel(DeclareAnnotation deca) {
		StringBuffer sb = new StringBuffer("");
		sb.append(deca.getPatternAsString());
		sb.append(" : ");
		sb.append(deca.getAnnotationString());
		return sb.toString();
	}

	private String genPrecedenceListLabel(TypePatternList list) {
		String tpList = "";
		for (int i = 0; i < list.size(); i++) {
			tpList += genTypePatternLabel(list.get(i));
			if (i < list.size() - 1) {
				tpList += ", ";
			}
		}
		return tpList;
	}

	// private String genArguments(MethodDeclaration md) {
	// String args = "";
	// Argument[] argArray = md.arguments;
	// if (argArray == null) return args;
	// for (int i = 0; i < argArray.length; i++) {
	// String argName = new String(argArray[i].name);
	// String argType = argArray[i].type.toString();
	// if (acceptArgument(argName, argType)) {
	// args += argType + ", ";
	// }
	// }
	// int lastSepIndex = args.lastIndexOf(',');
	// if (lastSepIndex != -1 && args.endsWith(", ")) args = args.substring(0, lastSepIndex);
	// return args;
	// }

	private String handleSigForReference(TypeReference ref, TypeBinding tb, MethodScope scope) {
		try {
			StringBuffer sb = new StringBuffer();
			createHandleSigForReference(ref, tb, scope, sb);
			return sb.toString();
		} catch (Throwable t) {
			System.err.println("Problem creating handle sig for this type reference " + ref);
			t.printStackTrace(System.err);
			return null;
		}
	}

	/**
	 * Aim of this method is create the signature for a parameter that can be used in a handle such that JDT can interpret the
	 * handle. Whether a type is qualified or unqualified in its source reference is actually reflected in the handle and this code
	 * allows for that.
	 */
	private void createHandleSigForReference(TypeReference ref, TypeBinding tb, MethodScope scope, StringBuffer handleSig) {
		if (ref instanceof Wildcard) {
			Wildcard w = (Wildcard) ref;
			if (w.bound == null) {
				handleSig.append('*');
			} else {
				handleSig.append('+');
				TypeBinding typeB = w.bound.resolvedType;
				if (typeB == null) {
					typeB = w.bound.resolveType(scope);
				}
				createHandleSigForReference(w.bound, typeB, scope, handleSig);
			}
		} else if (ref instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference pstr = (ParameterizedSingleTypeReference) ref;
			for (int i = pstr.dimensions(); i > 0; i--) {
				handleSig.append("\\[");
			}
			handleSig.append('Q').append(pstr.token);
			TypeReference[] typeRefs = pstr.typeArguments;
			if (typeRefs != null && typeRefs.length > 0) {
				handleSig.append("\\<");
				for (int i = 0; i < typeRefs.length; i++) {
					TypeReference typeR = typeRefs[i];
					TypeBinding typeB = typeR.resolvedType;
					if (typeB == null) {
						typeB = typeR.resolveType(scope);
					}
					createHandleSigForReference(typeR, typeB, scope, handleSig);
				}
				handleSig.append('>');
			}
			handleSig.append(';');
		} else if (ref instanceof ArrayTypeReference) {
			ArrayTypeReference atr = (ArrayTypeReference) ref;
			for (int i = 0; i < atr.dimensions; i++) {
				handleSig.append("\\[");
			}
			TypeBinding typeB = atr.resolvedType;
			if (typeB == null) {
				typeB = atr.resolveType(scope);
			}
			if (typeB.leafComponentType().isBaseType()) {
				handleSig.append(tb.leafComponentType().signature());
			} else {
				handleSig.append('Q').append(atr.token).append(';');
			}
		} else if (ref instanceof SingleTypeReference) {
			SingleTypeReference str = (SingleTypeReference) ref;
			if (tb.isBaseType()) {
				handleSig.append(tb.signature());
			} else {
				handleSig.append('Q').append(str.token).append(';');
			}
		} else if (ref instanceof ParameterizedQualifiedTypeReference) {
			ParameterizedQualifiedTypeReference pstr = (ParameterizedQualifiedTypeReference) ref;
			char[][] tokens = pstr.tokens;
			for (int i = pstr.dimensions(); i > 0; i--) {
				handleSig.append("\\[");
			}
			handleSig.append('Q');
			for (int i = 0; i < tokens.length; i++) {
				if (i > 0) {
					handleSig.append('.');
				}
				handleSig.append(tokens[i]);
				TypeReference[] typeRefs = pstr.typeArguments[i];
				if (typeRefs != null && typeRefs.length > 0) {
					handleSig.append("\\<");
					for (int j = 0; j < typeRefs.length; j++) {
						TypeReference typeR = typeRefs[j];
						TypeBinding typeB = typeR.resolvedType;
						if (typeB == null) {
							typeB = typeR.resolveType(scope);
						}
						createHandleSigForReference(typeR, typeB, scope, handleSig);
					}
					handleSig.append('>');
				}
			}
			handleSig.append(';');
		} else if (ref instanceof ArrayQualifiedTypeReference) {
			ArrayQualifiedTypeReference atr = (ArrayQualifiedTypeReference) ref;
			for (int i = 0; i < atr.dimensions(); i++) {
				handleSig.append("\\[");
			}
			TypeBinding typeB = atr.resolvedType;
			if (typeB == null) {
				typeB = atr.resolveType(scope);
			}
			if (typeB.leafComponentType().isBaseType()) {
				handleSig.append(tb.leafComponentType().signature());
			} else {
				char[][] tokens = atr.tokens;
				handleSig.append('Q');
				for (int i = 0; i < tokens.length; i++) {
					if (i > 0) {
						handleSig.append('.');
					}
					handleSig.append(tokens[i]);
				}
				handleSig.append(';');
			}
		} else if (ref instanceof QualifiedTypeReference) {
			QualifiedTypeReference qtr = (QualifiedTypeReference) ref;
			char[][] tokens = qtr.tokens;
			handleSig.append('Q');
			for (int i = 0; i < tokens.length; i++) {
				if (i > 0) {
					handleSig.append('.');
				}
				handleSig.append(tokens[i]);
			}
			handleSig.append(';');
		} else {
			throw new RuntimeException("Cant handle " + ref.getClass());
		}
	}

	public void setParameters(AbstractMethodDeclaration md, IProgramElement pe) {
		Argument[] argArray = md.arguments;
		if (argArray == null) {
			pe.setParameterNames(Collections.EMPTY_LIST);
			pe.setParameterSignatures(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
		} else {
			List<String> names = new ArrayList<String>();
			List<char[]> paramSigs = new ArrayList<char[]>();
			List<String> paramSourceRefs = new ArrayList<String>();
			boolean problemWithSourceRefs = false;
			for (int i = 0; i < argArray.length; i++) {
				String argName = new String(argArray[i].name);
				// String argType = "<UnknownType>"; // pr135052
				if (acceptArgument(argName, argArray[i].type.toString())) {
					TypeReference typeR = argArray[i].type;
					if (typeR != null && md.scope != null) {
						TypeBinding typeB = typeR.resolvedType;
						if (typeB == null) {
							typeB = typeR.resolveType(md.scope);
						}
						// This code will conjure up a 'P' style signature:
						// EclipseFactory factory = EclipseFactory.fromScopeLookupEnvironment(md.scope);
						// UnresolvedType ut = factory.fromBinding(typeB);
						// paramSigs.add(ut.getSignature().toCharArray());
						paramSigs.add(typeB.genericTypeSignature());
						String hsig = handleSigForReference(typeR, typeB, md.scope);
						if (hsig == null) {
							problemWithSourceRefs = true;
						} else {
							paramSourceRefs.add(hsig);
						}
					}
					names.add(argName);
				}
			}
			pe.setParameterNames(names);
			if (!paramSigs.isEmpty()) {
				pe.setParameterSignatures(paramSigs, (problemWithSourceRefs ? null : paramSourceRefs));
			}
		}
	}

	// TODO: fix this way of determing ajc-added arguments, make subtype of Argument with extra info
	private boolean acceptArgument(String name, String type) {
		if (name.charAt(0) != 'a' && type.charAt(0) != 'o') {
			return true;
		}
		return !name.startsWith("ajc$this_") && !type.equals("org.aspectj.lang.JoinPoint.StaticPart")
				&& !type.equals("org.aspectj.lang.JoinPoint") && !type.equals("org.aspectj.runtime.internal.AroundClosure");
	}

	public String genTypePatternLabel(TypePattern tp) {
		final String TYPE_PATTERN_LITERAL = "<type pattern>";
		String label;
		UnresolvedType typeX = tp.getExactType();

		if (!ResolvedType.isMissing(typeX)) {
			label = typeX.getName();
			if (tp.isIncludeSubtypes()) {
				label += "+";
			}
		} else {
			label = TYPE_PATTERN_LITERAL;
		}
		return label;

	}

	// // TODO:
	// private String translateAdviceName(String label) {
	// if (label.indexOf("before") != -1) return "before";
	// if (label.indexOf("returning") != -1) return "after returning";
	// if (label.indexOf("after") != -1) return "after";
	// if (label.indexOf("around") != -1) return "around";
	// else return "<advice>";
	// }

	// // !!! move or replace
	// private String translateDeclareName(String name) {
	// int colonIndex = name.indexOf(":");
	// if (colonIndex != -1) {
	// return name.substring(0, colonIndex);
	// } else {
	// return name;
	// }
	// }

	// !!! move or replace
	// private String translateInterTypeDecName(String name) {
	// int index = name.lastIndexOf('$');
	// if (index != -1) {
	// return name.substring(index+1);
	// } else {
	// return name;
	// }
	// }

	// !!! move or replace
	private String translatePointcutName(String name) {
		int index = name.indexOf("$$") + 2;
		int endIndex = name.lastIndexOf('$');
		if (index != -1 && endIndex != -1) {
			return name.substring(index, endIndex);
		} else {
			return name;
		}
	}

}
