/* Copyright (c) 2006-2009 Jan S. Rellermeyer
 * Systems Group,
 * Department of Computer Science, ETH Zurich.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    - Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    - Neither the name of ETH Zurich nor the names of its contributors may be
 *      used to endorse or promote products derived from this software without
 *      specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package ch.ethz.iks.r_osgi.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import ch.ethz.iks.r_osgi.messages.DeliverServiceMessage;
import ch.ethz.iks.util.StringUtils;

/**
 * <p>
 * The code analyzer takes a service interface together with additionally
 * registered parts (like smart proxies) and determines the injection set by
 * static code analysis.
 * </p>
 * <p>
 * The idea is to inject all types that are referenced by the service interface
 * so that the proxy becomes self-contained. However, at the current state, only
 * own types are injected. Imported types are not, since they are considered to
 * belong to the required environment.
 * <p>
 * <p>
 * For the moment, the code analysis does not cover accessed resources from the
 * bundle. In later revisions, it is likely that this will be introduced.
 * </p>
 * 
 * @author Jan S. Rellermeyer, ETH Zurich
 * @since 0.6
 */
final class CodeAnalyzer implements ClassVisitor {

	/**
	 * the class loader of the service provider bundle.
	 */
	private final ClassLoader loader;

	/**
	 * the closure list.
	 */
	private final ArrayList closure = new ArrayList();

	/**
	 * the set of already visited types.
	 */
	final HashSet visited = new HashSet();

	/**
	 * the injection set.
	 */
	private final HashMap injections = new HashMap();

	/**
	 * import map.
	 */
	private final HashMap importsMap;

	/**
	 * export map.
	 */
	private final HashMap exportsMap;

	/**
	 * imports of the proxy. Is generated during code analyis.
	 */
	private final HashSet proxyImports = new HashSet(0);

	/**
	 * exports of the proxy. Is generated during code analysis.
	 */
	private final HashSet proxyExports = new HashSet(0);

	/**
	 * the method analyzer.
	 */
	private final MethodVisitor methodVisitor = new MethodAnalyzer();

	private String currentClass;

	/**
	 * create a new code analyzer instance.
	 * 
	 * @param loader
	 *            the class loader of the service bundle.
	 * @param imports
	 *            the imports of the service bundle.
	 * @param exports
	 *            the exports of the service bundle.
	 */
	CodeAnalyzer(final ClassLoader loader, final String imports,
			final String exports) {
		this.loader = loader;

		if (imports != null) {
			final String[] tokens = StringUtils.stringToArray(imports, ","); //$NON-NLS-1$
			importsMap = new HashMap(tokens.length);
			for (int i = 0; i < tokens.length; i++) {
				final int pos = tokens[i].indexOf(";"); //$NON-NLS-1$
				if (pos > -1) {
					importsMap.put(tokens[i].substring(0, pos), tokens[i]
							.substring(pos + 1, tokens[i].length()));
				} else {
					importsMap.put(tokens[i], null);
				}
			}
		} else {
			importsMap = new HashMap(0);
		}

		if (exports != null) {
			final String[] tokens = StringUtils.stringToArray(exports, ","); //$NON-NLS-1$
			exportsMap = new HashMap(tokens.length);
			for (int i = 0; i < tokens.length; i++) {
				final int pos = tokens[i].indexOf(";"); //$NON-NLS-1$
				if (pos > -1) {
					exportsMap.put(tokens[i].substring(0, pos), tokens[i]
							.substring(pos + 1, tokens[i].length()));
				} else {
					exportsMap.put(tokens[i], null);
				}
			}
		} else {
			exportsMap = new HashMap(0);
		}
	}

	/**
	 * analyze the service.
	 * 
	 * @param iface
	 *            the service interface class name.
	 * @param smartProxy
	 *            the smart proxy class name or <code>null</code>
	 * @param explicitInjections
	 *            the injection array or <code>null</code>
	 * @param presentation
	 *            the presentation class name or <code>null</code>
	 * @return the <code>DeliverServiceMessage</code> that contains all
	 *         information required to build a proxy on the client side. This
	 *         message is generic, can be cached and initialized for a concrete
	 *         requesting peer by calling the <code>init</code> method.
	 * @throws ClassNotFoundException
	 * @throws IOException
	 */
	DeliverServiceMessage analyze(final String[] ifaces,
			final String smartProxy, final String[] explicitInjections,
			final String presentation) throws ClassNotFoundException,
			IOException {		
		
		closure.addAll(Arrays.asList(ifaces));

		if (smartProxy != null) {
			closure.add(smartProxy);
		}
		if (presentation != null) {
			closure.add(presentation);
		}
		if (explicitInjections != null) {
			closure.addAll(Arrays.asList(explicitInjections));
		}
		
		while (!closure.isEmpty()) {
			visit((String) closure.remove(0));
		}
		
		for (int i = 0; i < ifaces.length; i++) {
			proxyImports.add(packageOf(ifaces[i]));
			proxyExports.add(packageOf(ifaces[i]));
		}

		// remove the obvious imports to save network bandwidth
		proxyImports.remove("org.osgi.framework"); //$NON-NLS-1$
		proxyImports.remove("ch.ethz.iks.r_osgi"); //$NON-NLS-1$
		proxyImports.remove("ch.ethz.iks.r_osgi.types"); //$NON-NLS-1$
		proxyImports.remove("ch.ethz.iks.r_osgi.channels"); //$NON-NLS-1$

		final StringBuffer importDeclaration = new StringBuffer();
		final StringBuffer exportDeclaration = new StringBuffer();
		final String[] pi = (String[]) proxyImports
				.toArray(new String[proxyImports.size()]);
		
		for (int i = 0; i < pi.length; i++) {
			importDeclaration.append(pi[i]);
			final Object v = importsMap.get(pi[i]);
			if (v != null) {
				importDeclaration.append("; "); //$NON-NLS-1$
				importDeclaration.append(v);
			}
			if (i < pi.length - 1) {
				importDeclaration.append(", "); //$NON-NLS-1$
			}
		}

		final String[] pe = (String[]) proxyExports
				.toArray(new String[proxyExports.size()]);
		for (int i = 0; i < pe.length; i++) {
			exportDeclaration.append(pe[i]);
			final Object v = exportsMap.get(pe[i]);
			if (v != null) {
				exportDeclaration.append("; "); //$NON-NLS-1$
				exportDeclaration.append(v);
			}
			if (i < pe.length - 1) {
				exportDeclaration.append(", "); //$NON-NLS-1$
			}
		}

		final DeliverServiceMessage message = new DeliverServiceMessage();
		message.setInterfaceNames(ifaces);
		message.setSmartProxyName(smartProxy);
		message.setInjections((HashMap) injections.clone());
		message.setImports(importDeclaration.toString());
		message.setExports(exportDeclaration.toString());

		visited.clear();
		injections.clear();
		closure.clear();
		return message;
	}

	/**
	 * visit a class.
	 * 
	 * @param className
	 *            the class name.
	 * @throws ClassNotFoundException
	 *             if the class is unknown.
	 * @throws IOException
	 *             if the classes bytecode cannot be found and accessed.
	 */
	private void visit(final String className) throws ClassNotFoundException {
		currentClass = className.replace('.', '/');
		// remove array indicators 
		if(currentClass.startsWith("[L")) {
			currentClass = currentClass.substring(2);
		} else if (currentClass.startsWith("L")) {
			currentClass = currentClass.substring(1);
		}
		final String classFile = currentClass + ".class"; //$NON-NLS-1$

		final String pkg = packageOf(className);

		if (importsMap.containsKey(pkg) || exportsMap.containsKey(pkg)) {
			proxyExports.add(pkg);
		}
		try {
			final ClassReader reader = new ClassReader(loader
					.getResourceAsStream(classFile));

			injections.put(classFile, reader.b);
			if (exportsMap.containsKey(pkg)) {
				proxyExports.add(pkg);
			}
			reader.accept(this, ClassReader.SKIP_DEBUG 
					+ ClassReader.SKIP_FRAMES);
		} catch (final IOException ioe) {
			throw new ClassNotFoundException(className);
		}
	}

	/**
	 * get the package of a class.
	 * 
	 * @param cls
	 *            the class.
	 * @return the package name.
	 */
	private String packageOf(final String cls) {
		final int p = cls.lastIndexOf("."); //$NON-NLS-1$
		return p > -1 ? cls.substring(0, p).trim() : ""; //$NON-NLS-1$
	}

	/**
	 * visit a type.
	 * 
	 * @param t
	 *            the type.
	 */
	void visitType(final Type t) {
		
		if (t.getSort() < Type.ARRAY) {
			visited.add(t.getClassName());
			return;
		}
		if (t.getSort() == Type.ARRAY) {
			visitType(t.getElementType());
			return;
		}

		if ("null".equals(t.getClassName())) { //$NON-NLS-1$
			return;
		}

		final String className = t.getClassName();
		final String iClassName = className.replace('.', '/');
		if (visited.contains(iClassName)) {
			return;
		}

		// do not inject java* classes
		if (className.startsWith("java")) { //$NON-NLS-1$
			visited.add(iClassName);
			return;
		}

		final String pkg = packageOf(className);
		if (importsMap.containsKey(pkg)) {
			visited.add(iClassName);
			proxyImports.add(pkg);
			return;
		}

		// do not inject osgi classes
		if (className.startsWith("org.osgi")) { //$NON-NLS-1$
			visited.add(iClassName);
			return;
		}

		visited.add(iClassName);
		closure.add(className);
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String,
	 *      java.lang.String, java.lang.String, java.lang.String[])
	 */
	public void visit(final int version, final int access, final String name,
			final String signature, final String superName,
			final String[] interfaces) {
		
		if (superName != null && !visited.contains(superName)) {
			visitType(Type.getType('L' + superName + ';'));
		}

		for (int i = 0; i < interfaces.length; i++) {
			if (!visited.contains(interfaces[i])) {
				visitType(Type.getType('L' + interfaces[i] + ';'));
			}
		}
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String,
	 *      boolean)
	 */
	public AnnotationVisitor visitAnnotation(final String desc,
			final boolean visible) {
		return null;
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
	 */
	public void visitAttribute(final Attribute attr) {
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitEnd()
	 */
	public void visitEnd() {
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String,
	 *      java.lang.String, java.lang.String, java.lang.Object)
	 */
	public FieldVisitor visitField(final int access, final String name,
			final String desc, final String signature, final Object value) {
		if (!visited.contains(desc)) {
			visitType(Type.getType(desc));
		}
		return null;
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String,
	 *      java.lang.String, java.lang.String, int)
	 */
	public void visitInnerClass(final String name, final String outerName,
			final String innerName, final int access) {
		if (!name.equals(currentClass) && !visited.contains(currentClass)) {
			closure.add(name.replace('/', '.'));
		}
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String,
	 *      java.lang.String, java.lang.String, java.lang.String[])
	 */
	public MethodVisitor visitMethod(final int access, final String name,
			final String desc, final String signature, final String[] exceptions) {
		final Type[] methodTypes = Type.getArgumentTypes(desc);
		for (int i = 0; i < methodTypes.length; i++) {
			if (!visited.contains(methodTypes[i].getClassName().replace('.',
					'/'))) {
				visitType(methodTypes[i]);
			}
		}
		final Type returnType = Type.getReturnType(desc);
		if (!visited.contains(returnType.getClassName().replace('.', '/'))) {
			visitType(returnType);
		}

		if (exceptions != null) {
			for (int i = 0; i < exceptions.length; i++) {
				if (!visited.contains(exceptions[i])) {
					visitType(Type.getType('L' + exceptions[i] + ';'));
				}
			}
		}

		if ((access & Opcodes.ACC_ABSTRACT) == 0) {
			return methodVisitor;
		} else {
			return null;
		}
	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public void visitOuterClass(final String owner, final String name,
			final String desc) {

	}

	/**
	 * 
	 * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String,
	 *      java.lang.String)
	 */
	public void visitSource(final String source, final String debug) {

	}

	/**
	 * the method analyzer.
	 * 
	 * @author Jan S. Rellermeyer, ETH Zurich
	 */
	final class MethodAnalyzer implements MethodVisitor {

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitAnnotation(java.lang.String,
		 *      boolean)
		 */
		public AnnotationVisitor visitAnnotation(final String desc,
				final boolean visible) {
			if (!visited.contains(desc)) {
				visitType(Type.getType("L" + desc + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return null;
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitAnnotationDefault()
		 */
		public AnnotationVisitor visitAnnotationDefault() {
			return null;
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitAttribute(org.objectweb.asm.Attribute)
		 */
		public void visitAttribute(final Attribute attr) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitCode()
		 */
		public void visitCode() {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitEnd()
		 */
		public void visitEnd() {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int,
		 *      java.lang.String, java.lang.String, java.lang.String)
		 */
		public void visitFieldInsn(final int opcode, final String owner,
				final String name, final String desc) {
			if (!visited.contains(owner)) {
				visitType(Type.getType("L" + owner + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
			if (!visited.contains(desc)) {
				visitType(Type.getType(desc)); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitIincInsn(int, int)
		 */
		public void visitIincInsn(final int var, final int increment) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitInsn(int)
		 */
		public void visitInsn(final int opcode) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitIntInsn(int, int)
		 */
		public void visitIntInsn(final int opcode, final int operand) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitJumpInsn(int,
		 *      org.objectweb.asm.Label)
		 */
		public void visitJumpInsn(final int opcode, final Label label) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitLabel(org.objectweb.asm.Label)
		 */
		public void visitLabel(final Label label) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitLdcInsn(java.lang.Object)
		 */
		public void visitLdcInsn(final Object cst) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitLineNumber(int,
		 *      org.objectweb.asm.Label)
		 */
		public void visitLineNumber(final int line, final Label start) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitLocalVariable(java.lang.String,
		 *      java.lang.String, java.lang.String, org.objectweb.asm.Label,
		 *      org.objectweb.asm.Label, int)
		 */
		public void visitLocalVariable(final String name, final String desc,
				final String signature, final Label start, final Label end,
				final int index) {
			if (!visited.contains(desc)) {
				visitType(Type.getType("L" + desc + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn(org.objectweb.asm.Label,
		 *      int[], org.objectweb.asm.Label[])
		 */
		public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
				final Label[] labels) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitMaxs(int, int)
		 */
		public void visitMaxs(final int maxStack, final int maxLocals) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitMethodInsn(int,
		 *      java.lang.String, java.lang.String, java.lang.String)
		 */
		public void visitMethodInsn(final int opcode, final String owner,
				final String name, final String desc) {
			if (!visited.contains(owner)) {
				visitType(Type.getType("L" + owner + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn(java.lang.String,
		 *      int)
		 */
		public void visitMultiANewArrayInsn(final String desc, final int dims) {
			if (!visited.contains(desc)) {
				visitType(Type.getType("L" + desc + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitParameterAnnotation(int,
		 *      java.lang.String, boolean)
		 */
		public AnnotationVisitor visitParameterAnnotation(final int parameter,
				final String desc, final boolean visible) {
			if (!visited.contains(desc)) {
				visitType(Type.getType("L" + desc + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return null;
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitTableSwitchInsn(int, int,
		 *      org.objectweb.asm.Label, org.objectweb.asm.Label[])
		 */
		public void visitTableSwitchInsn(final int min, final int max,
				final Label dflt, final Label[] labels) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitTryCatchBlock(org.objectweb.asm.Label,
		 *      org.objectweb.asm.Label, org.objectweb.asm.Label,
		 *      java.lang.String)
		 */
		public void visitTryCatchBlock(final Label start, final Label end,
				final Label handler, final String type) {
			if (!visited.contains(type)) {
				visitType(Type.getType("L" + type + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitTypeInsn(int,
		 *      java.lang.String)
		 */
		public void visitTypeInsn(final int opcode, final String desc) {
			if (!visited.contains(desc)) {
				visitType(Type.getType("L" + desc + ";")); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitVarInsn(int, int)
		 */
		public void visitVarInsn(final int opcode, final int var) {
		}

		/**
		 * 
		 * @see org.objectweb.asm.MethodVisitor#visitFrame(int, int,
		 *      java.lang.Object[], int, java.lang.Object[])
		 */
		public void visitFrame(final int arg0, final int arg1,
				final Object[] arg2, final int arg3, final Object[] arg4) {

		}

	}

}
