/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.common.bytecode;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.LoaderClassPath;
import javassist.NotFoundException;

import com.alibaba.dubbo.common.utils.ReflectUtils;

/**
 * ClassGenerator
 * 
 * @author qian.lei
 */

public final class ClassGenerator
{
	public static interface DC{} // dynamic class tag interface.

	private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(0);

	private static final String SIMPLE_NAME_TAG = "<init>";

	private static final Map<ClassLoader, ClassPool> POOL_MAP = new ConcurrentHashMap<ClassLoader, ClassPool>(); //ClassLoader - ClassPool

	public static ClassGenerator newInstance()
	{
		return new ClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader()));
	}

	public static ClassGenerator newInstance(ClassLoader loader)
	{
		return new ClassGenerator(getClassPool(loader));
	}

	public static boolean isDynamicClass(Class<?> cl)
	{
		return ClassGenerator.DC.class.isAssignableFrom(cl);
	}

	public static ClassPool getClassPool(ClassLoader loader)
	{
		if( loader == null )
			return ClassPool.getDefault();

		ClassPool pool = POOL_MAP.get(loader);
		if( pool == null )
		{
			pool = new ClassPool(true);
			pool.appendClassPath(new LoaderClassPath(loader));
			POOL_MAP.put(loader, pool);
		}
		return pool;
	}

	private ClassPool mPool;

	private CtClass mCtc;

	private String mClassName, mSuperClass;

	private Set<String> mInterfaces;

	private List<String> mFields, mConstructors, mMethods;

	private Map<String, Method> mCopyMethods; // <method desc,method instance>

	private Map<String, Constructor<?>> mCopyConstructors; // <constructor desc,constructor instance>

	private boolean mDefaultConstructor = false;

	private ClassGenerator(){}

	private ClassGenerator(ClassPool pool)
	{
		mPool = pool;
	}

	public String getClassName()
	{
		return mClassName;
	}

	public ClassGenerator setClassName(String name)
	{
		mClassName = name;
		return this;
	}

	public ClassGenerator addInterface(String cn)
	{
		if( mInterfaces == null )
			mInterfaces = new HashSet<String>();
		mInterfaces.add(cn);
		return this;
	}

	public ClassGenerator addInterface(Class<?> cl)
	{
		return addInterface(cl.getName());
	}

	public ClassGenerator setSuperClass(String cn)
	{
		mSuperClass = cn;
		return this;
	}

	public ClassGenerator setSuperClass(Class<?> cl)
	{
		mSuperClass = cl.getName();
		return this;
	}

	public ClassGenerator addField(String code)
	{
		if( mFields == null )
			mFields = new ArrayList<String>();
		mFields.add(code);
		return this;
	}

	public ClassGenerator addField(String name, int mod, Class<?> type)
	{
		return addField(name, mod, type, null);
	}

	public ClassGenerator addField(String name, int mod, Class<?> type, String def)
	{
		StringBuilder sb = new StringBuilder();
		sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(type)).append(' ');
		sb.append(name);
		if( def != null && def.length() > 0 )
		{
			sb.append('=');
			sb.append(def);
		}
		sb.append(';');
		return addField(sb.toString());
	}

	public ClassGenerator addMethod(String code)
	{
		if( mMethods == null )
			mMethods = new ArrayList<String>();
		mMethods.add(code);
		return this;
	}

	public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, String body)
	{
		return addMethod(name, mod, rt, pts, null, body);
	}

	public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, Class<?>[] ets, String body)
	{
		StringBuilder sb = new StringBuilder();
		sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(rt)).append(' ').append(name);
		sb.append('(');
		for(int i=0;i<pts.length;i++)
		{
			if( i > 0 )
				sb.append(',');
			sb.append(ReflectUtils.getName(pts[i]));
			sb.append(" arg").append(i);
		}
		sb.append(')');
		if( ets != null && ets.length > 0 )
		{
			sb.append(" throws ");
			for(int i=0;i<ets.length;i++)
			{
				if( i > 0 )
					sb.append(',');
				sb.append(ReflectUtils.getName(ets[i]));
			}
		}
		sb.append('{').append(body).append('}');
		return addMethod(sb.toString());
	}

	public ClassGenerator addMethod(Method m)
	{
		addMethod(m.getName(), m);
		return this;
	}

	public ClassGenerator addMethod(String name, Method m)
	{
		String desc = name + ReflectUtils.getDescWithoutMethodName(m);
		addMethod(':' + desc);
		if( mCopyMethods == null )
			mCopyMethods = new ConcurrentHashMap<String, Method>(8);
		mCopyMethods.put(desc, m);
		return this;
	}

	public ClassGenerator addConstructor(String code)
	{
		if( mConstructors == null )
			mConstructors = new LinkedList<String>();
		mConstructors.add(code);
		return this;
	}

	public ClassGenerator addConstructor(int mod, Class<?>[] pts, String body)
	{
		return addConstructor(mod, pts, null, body);
	}

	public ClassGenerator addConstructor(int mod, Class<?>[] pts, Class<?>[] ets, String body)
	{
		StringBuilder sb = new StringBuilder();
		sb.append(modifier(mod)).append(' ').append(SIMPLE_NAME_TAG);
		sb.append('(');
		for(int i=0;i<pts.length;i++)
		{
			if( i > 0 )
				sb.append(',');
			sb.append(ReflectUtils.getName(pts[i]));
			sb.append(" arg").append(i);
		}
		sb.append(')');
		if( ets != null && ets.length > 0 )
		{
			sb.append(" throws ");
			for(int i=0;i<ets.length;i++)
			{
				if( i > 0 )
					sb.append(',');
				sb.append(ReflectUtils.getName(ets[i]));
			}
		}
		sb.append('{').append(body).append('}');
		return addConstructor(sb.toString());
	}

	public ClassGenerator addConstructor(Constructor<?> c)
	{
		String desc = ReflectUtils.getDesc(c);
		addConstructor(":"+desc);
		if( mCopyConstructors == null )
			mCopyConstructors = new ConcurrentHashMap<String, Constructor<?>>(4);
		mCopyConstructors.put(desc, c);
		return this;
	}

	public ClassGenerator addDefaultConstructor()
	{
		mDefaultConstructor = true;
		return this;
	}

	public ClassPool getClassPool() {
	    return mPool;
	}

	public Class<?> toClass()
	{
		if( mCtc != null )
			mCtc.detach();
		long id = CLASS_NAME_COUNTER.getAndIncrement();
		try
		{
			CtClass ctcs = mSuperClass == null ? null : mPool.get(mSuperClass);
			if( mClassName == null )
				mClassName = ( mSuperClass == null || javassist.Modifier.isPublic(ctcs.getModifiers())
						? ClassGenerator.class.getName() : mSuperClass + "$sc" ) + id;
			mCtc = mPool.makeClass(mClassName);
			if( mSuperClass != null )
				mCtc.setSuperclass(ctcs);
			mCtc.addInterface(mPool.get(DC.class.getName())); // add dynamic class tag.
			if( mInterfaces != null )
				for( String cl : mInterfaces ) mCtc.addInterface(mPool.get(cl));
			if( mFields != null )
				for( String code : mFields ) mCtc.addField(CtField.make(code, mCtc));
			if( mMethods != null )
			{
				for( String code : mMethods )
				{
					if( code.charAt(0) == ':' )
						mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))), code.substring(1, code.indexOf('(')), mCtc, null));
					else
						mCtc.addMethod(CtNewMethod.make(code, mCtc));
				}
			}
			if( mDefaultConstructor )
				mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
			if( mConstructors != null )
			{
				for( String code : mConstructors )
				{
					if( code.charAt(0) == ':' )
					{
						mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null));
					}
					else
					{
						String[] sn = mCtc.getSimpleName().split("\\$+"); // inner class name include $.
						mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length-1]), mCtc));
					}
				}
			}
			return mCtc.toClass();
		}
		catch(RuntimeException e)
		{
			throw e;
		}
		catch(NotFoundException e)
		{
			throw new RuntimeException(e.getMessage(), e);
		}
		catch(CannotCompileException e)
		{
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	public void release()
	{
		if( mCtc != null ) mCtc.detach();
		if( mInterfaces != null ) mInterfaces.clear();
		if( mFields != null ) mFields.clear();
		if( mMethods != null ) mMethods.clear();
		if( mConstructors != null ) mConstructors.clear();
		if( mCopyMethods != null ) mCopyMethods.clear();
		if( mCopyConstructors != null ) mCopyConstructors.clear();
	}

	private CtClass getCtClass(Class<?> c) throws NotFoundException
	{
		return mPool.get(c.getName());
	}

	private CtMethod getCtMethod(Method m) throws NotFoundException
	{
		return getCtClass(m.getDeclaringClass()).getMethod(m.getName(),ReflectUtils.getDescWithoutMethodName(m));
	}

	private CtConstructor getCtConstructor(Constructor<?> c) throws NotFoundException
	{
		return getCtClass(c.getDeclaringClass()).getConstructor(ReflectUtils.getDesc(c));
	}

	private static String modifier(int mod)
	{
		if( Modifier.isPublic(mod) ) return "public";
		if( Modifier.isProtected(mod) ) return "protected";
		if( Modifier.isPrivate(mod) ) return "private";
		return "";
	}
}