/*
 * $Id: DefaultConverter.java,v 1.1 2008/10/28 16:36:48 anaef Exp $
 * See LICENSE.txt for license terms.
 */

package com.naef.jnlua;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.naef.jnlua.util.AbstractTableList;
import com.naef.jnlua.util.AbstractTableMap;

/**
 * Default implementation of the <code>Converter</code> interface.
 */
public class DefaultConverter implements Converter {
	// -- Static
	/**
	 * Static instance.
	 */
	private static final DefaultConverter INSTANCE = new DefaultConverter();

	/**
	 * Boolean distance map.
	 */
	private static final Map<Class<?>, Integer> BOOLEAN_DISTANCE_MAP = new HashMap<Class<?>, Integer>();
	static {
		BOOLEAN_DISTANCE_MAP.put(Boolean.class, Integer.valueOf(1));
		BOOLEAN_DISTANCE_MAP.put(Boolean.TYPE, Integer.valueOf(1));
		BOOLEAN_DISTANCE_MAP.put(Object.class, Integer.valueOf(2));
	}

	/**
	 * Number distance map.
	 */
	private static final Map<Class<?>, Integer> NUMBER_DISTANCE_MAP = new HashMap<Class<?>, Integer>();
	static {
		NUMBER_DISTANCE_MAP.put(Byte.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Byte.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Short.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Short.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Integer.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Integer.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Long.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Long.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Float.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Float.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Double.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Double.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(BigInteger.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(BigDecimal.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Character.class, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Character.TYPE, Integer.valueOf(1));
		NUMBER_DISTANCE_MAP.put(Object.class, Integer.valueOf(2));
		NUMBER_DISTANCE_MAP.put(String.class, Integer.valueOf(3));
	}

	/**
	 * String distance map.
	 */
	private static final Map<Class<?>, Integer> STRING_DISTANCE_MAP = new HashMap<Class<?>, Integer>();
	static {
		STRING_DISTANCE_MAP.put(String.class, Integer.valueOf(1));
		STRING_DISTANCE_MAP.put(Object.class,Integer.valueOf(2));
		STRING_DISTANCE_MAP.put(Byte.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Byte.TYPE, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Short.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Short.TYPE, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Integer.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Integer.TYPE, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Long.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Long.TYPE, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Float.class,Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Float.TYPE,Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Double.class,Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Double.TYPE, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(BigInteger.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(BigDecimal.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Character.class, Integer.valueOf(3));
		STRING_DISTANCE_MAP.put(Character.TYPE, Integer.valueOf(3));
	}

	/**
	 * Function distance map.
	 */
	private static final Map<Class<?>, Integer> FUNCTION_DISTANCE_MAP = new HashMap<Class<?>, Integer>();
	static {
		FUNCTION_DISTANCE_MAP.put(JavaFunction.class, Integer.valueOf(1));
		FUNCTION_DISTANCE_MAP.put(Object.class, Integer.valueOf(2));
	}

	/**
	 * Lua value converters.
	 */
	private static final Map<Class<?>, LuaValueConverter<?>> LUA_VALUE_CONVERTERS = new HashMap<Class<?>, LuaValueConverter<?>>();
	static {
		LuaValueConverter<Boolean> booleanConverter = new LuaValueConverter<Boolean>() {
			@Override
			public Boolean convert(LuaState luaState, int index) {
				return Boolean.valueOf(luaState.toBoolean(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Boolean.class, booleanConverter);
		LUA_VALUE_CONVERTERS.put(Boolean.TYPE, booleanConverter);

		LuaValueConverter<Byte> byteConverter = new LuaValueConverter<Byte>() {
			@Override
			public Byte convert(LuaState luaState, int index) {
				return Byte.valueOf((byte) luaState.toInteger(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Byte.class, byteConverter);
		LUA_VALUE_CONVERTERS.put(Byte.TYPE, byteConverter);
		LuaValueConverter<Short> shortConverter = new LuaValueConverter<Short>() {
			@Override
			public Short convert(LuaState luaState, int index) {
				return Short.valueOf((short) luaState.toInteger(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Short.class, shortConverter);
		LUA_VALUE_CONVERTERS.put(Short.TYPE, shortConverter);
		LuaValueConverter<Integer> integerConverter = new LuaValueConverter<Integer>() {
			@Override
			public Integer convert(LuaState luaState, int index) {
				return Integer.valueOf(luaState.toInteger(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Integer.class, integerConverter);
		LUA_VALUE_CONVERTERS.put(Integer.TYPE, integerConverter);
		LuaValueConverter<Long> longConverter = new LuaValueConverter<Long>() {
			@Override
			public Long convert(LuaState luaState, int index) {
				return Long.valueOf((long) luaState.toNumber(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Long.class, longConverter);
		LUA_VALUE_CONVERTERS.put(Long.TYPE, longConverter);
		LuaValueConverter<Float> floatConverter = new LuaValueConverter<Float>() {
			@Override
			public Float convert(LuaState luaState, int index) {
				return Float.valueOf((float) luaState.toNumber(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Float.class, floatConverter);
		LUA_VALUE_CONVERTERS.put(Float.TYPE, floatConverter);
		LuaValueConverter<Double> doubleConverter = new LuaValueConverter<Double>() {
			@Override
			public Double convert(LuaState luaState, int index) {
				return Double.valueOf(luaState.toNumber(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Double.class, doubleConverter);
		LUA_VALUE_CONVERTERS.put(Double.TYPE, doubleConverter);
		LuaValueConverter<BigInteger> bigIntegerConverter = new LuaValueConverter<BigInteger>() {
			@Override
			public BigInteger convert(LuaState luaState, int index) {
				return BigDecimal.valueOf(luaState.toNumber(index)).setScale(0,
						BigDecimal.ROUND_HALF_EVEN).toBigInteger();
			}
		};
		LUA_VALUE_CONVERTERS.put(BigInteger.class, bigIntegerConverter);
		LuaValueConverter<BigDecimal> bigDecimalConverter = new LuaValueConverter<BigDecimal>() {
			@Override
			public BigDecimal convert(LuaState luaState, int index) {
				return BigDecimal.valueOf(luaState.toNumber(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(BigDecimal.class, bigDecimalConverter);
		LuaValueConverter<Character> characterConverter = new LuaValueConverter<Character>() {
			@Override
			public Character convert(LuaState luaState, int index) {
				return Character.valueOf((char) luaState.toInteger(index));
			}
		};
		LUA_VALUE_CONVERTERS.put(Character.class, characterConverter);
		LUA_VALUE_CONVERTERS.put(Character.TYPE, characterConverter);
		LuaValueConverter<String> stringConverter = new LuaValueConverter<String>() {
			@Override
			public String convert(LuaState luaState, int index) {
				return luaState.toString(index);
			}
		};
		LUA_VALUE_CONVERTERS.put(String.class, stringConverter);
	}

	/**
	 * Java object converters.
	 */
	private static final Map<Class<?>, JavaObjectConverter<?>> JAVA_OBJECT_CONVERTERS = new HashMap<Class<?>, JavaObjectConverter<?>>();
	static {
		JavaObjectConverter<Boolean> booleanConverter = new JavaObjectConverter<Boolean>() {
			@Override
			public void convert(LuaState luaState, Boolean booleanValue) {
				luaState.pushBoolean(booleanValue.booleanValue());
			}
		};
		JAVA_OBJECT_CONVERTERS.put(Boolean.class, booleanConverter);
		JAVA_OBJECT_CONVERTERS.put(Boolean.TYPE, booleanConverter);
		JavaObjectConverter<Number> numberConverter = new JavaObjectConverter<Number>() {
			@Override
			public void convert(LuaState luaState, Number number) {
				luaState.pushNumber(number.doubleValue());
			}
		};
		JAVA_OBJECT_CONVERTERS.put(Byte.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Byte.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Short.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Short.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Integer.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Integer.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Long.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Long.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Float.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Float.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Double.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(Double.TYPE, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(BigInteger.class, numberConverter);
		JAVA_OBJECT_CONVERTERS.put(BigDecimal.class, numberConverter);
		JavaObjectConverter<Character> characterConverter = new JavaObjectConverter<Character>() {
			@Override
			public void convert(LuaState luaState, Character character) {
				luaState.pushInteger(character.charValue());
			}
		};
		JAVA_OBJECT_CONVERTERS.put(Character.class, characterConverter);
		JAVA_OBJECT_CONVERTERS.put(Character.TYPE, characterConverter);
		JavaObjectConverter<String> stringConverter = new JavaObjectConverter<String>() {
			@Override
			public void convert(LuaState luaState, String string) {
				luaState.pushString(string);
			}
		};
		JAVA_OBJECT_CONVERTERS.put(String.class, stringConverter);
	}

	// -- Static methods
	/**
	 * Returns the instance of this class.
	 * 
	 * @return the instance
	 */
	public static DefaultConverter getInstance() {
		return INSTANCE;
	}

	// -- Construction
	/**
	 * Singleton.
	 */
	private DefaultConverter() {
	}

	// -- Java converter methods
	@Override
	public int getTypeDistance(LuaState luaState, int index, Class<?> formalType) {
		// Handle void
		if (formalType == Void.TYPE) {
			return Integer.MAX_VALUE;
		}

		// Handle Lua value proxy
		if (formalType == LuaValueProxy.class) {
			return 0;
		}

		// Handle Lua types
		switch (luaState.type(index)) {
		case NIL:
			return 1;
		case BOOLEAN:
			Integer distance = BOOLEAN_DISTANCE_MAP.get(formalType);
			if (distance != null) {
				return distance.intValue();
			}
			break;
		case NUMBER:
			distance = NUMBER_DISTANCE_MAP.get(formalType);
			if (distance != null) {
				return distance.intValue();
			}
			break;
		case STRING:
			distance = STRING_DISTANCE_MAP.get(formalType);
			if (distance != null) {
				return distance.intValue();
			}
			break;
		case TABLE:
			if (formalType == Map.class || formalType == List.class
					|| formalType.isArray()) {
				return 1;
			}
			if (formalType == Object.class) {
				return 2;
			}
			break;
		case FUNCTION:
			if (luaState.isJavaFunction(index)) {
				distance = FUNCTION_DISTANCE_MAP.get(formalType);
				if (distance != null) {
					return distance.intValue();
				}
			}
			break;
		case USERDATA:
			Object object = luaState.toJavaObjectRaw(index);
			if (object != null) {
				Class<?> type;
				if (object instanceof TypedJavaObject) {
					TypedJavaObject typedJavaObject = (TypedJavaObject) object;
					if (typedJavaObject.isStrong()) {
						if (formalType.isAssignableFrom(typedJavaObject
								.getClass())) {
							return 1;
						}
					}
					type = typedJavaObject.getType();
				} else {
					type = object.getClass();
				}
				if (formalType.isAssignableFrom(type)) {
					return 1;
				}
			}
			break;
		}

		// Handle object
		if (formalType == Object.class) {
			return Integer.MAX_VALUE - 1;
		}

		// Unsupported conversion
		return Integer.MAX_VALUE;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T convertLuaValue(LuaState luaState, int index,
			Class<T> formalType) {
		// Handle void
		if (formalType == Void.TYPE) {
			throw new ClassCastException(String.format(
					"cannot convert %s to %s", luaState.typeName(index),
					formalType.getCanonicalName()));
		}

		// Handle Lua value proxy
		if (formalType == LuaValueProxy.class) {
			return (T) luaState.getProxy(index);
		}

		// Handle Lua types
		switch (luaState.type(index)) {
		case NIL:
			return null;
		case BOOLEAN:
			LuaValueConverter<?> luaValueConverter;
			luaValueConverter = LUA_VALUE_CONVERTERS.get(formalType);
			if (luaValueConverter != null) {
				return (T) luaValueConverter.convert(luaState, index);
			}
			if (formalType == Object.class) {
				return (T) Boolean.valueOf(luaState.toBoolean(index));
			}
			break;
		case NUMBER:
			luaValueConverter = LUA_VALUE_CONVERTERS.get(formalType);
			if (luaValueConverter != null) {
				return (T) luaValueConverter.convert(luaState, index);
			}
			if (formalType == Object.class) {
				return (T) Double.valueOf(luaState.toNumber(index));
			}
			break;
		case STRING:
			luaValueConverter = LUA_VALUE_CONVERTERS.get(formalType);
			if (luaValueConverter != null) {
				return (T) luaValueConverter.convert(luaState, index);
			}
			if (formalType == Object.class) {
				return (T) luaState.toString(index);
			}
			break;
		case TABLE:
			if (formalType == Map.class || formalType == Object.class) {
				final LuaValueProxy luaValueProxy = luaState.getProxy(index);
				return (T) new AbstractTableMap<Object>() {
					@Override
					protected Object convertKey(int index) {
						return getLuaState().toJavaObject(index, Object.class);
					}

					@Override
					public LuaState getLuaState() {
						return luaValueProxy.getLuaState();
					}

					@Override
					public void pushValue() {
						luaValueProxy.pushValue();
					}
				};
			}
			if (formalType == List.class) {
				final LuaValueProxy luaValueProxy = luaState.getProxy(index);
				return (T) new AbstractTableList() {
					@Override
					public LuaState getLuaState() {
						return luaValueProxy.getLuaState();
					}

					@Override
					public void pushValue() {
						luaValueProxy.pushValue();
					}
				};
			}
			if (formalType.isArray()) {
				int length = luaState.length(index);
				Class<?> componentType = formalType.getComponentType();
				Object array = Array.newInstance(formalType.getComponentType(),
						length);
				for (int i = 0; i < length; i++) {
					luaState.rawGet(index, i + 1);
					try {
						Array.set(array, i, convertLuaValue(luaState, -1,
								componentType));
					} finally {
						luaState.pop(1);
					}
				}
				return (T) array;
			}
			break;
		case FUNCTION:
			if (luaState.isJavaFunction(index)) {
				if (formalType == JavaFunction.class
						|| formalType == Object.class) {
					return (T) luaState.toJavaFunction(index);
				}
			}
			break;
		case USERDATA:
			Object object = luaState.toJavaObjectRaw(index);
			if (object != null) {
				if (object instanceof TypedJavaObject) {
					TypedJavaObject typedJavaObject = (TypedJavaObject) object;
					if (typedJavaObject.isStrong()) {
						if (formalType.isAssignableFrom(typedJavaObject
								.getClass())) {
							return (T) typedJavaObject;
						}
					}
					return (T) ((TypedJavaObject) object).getObject();
				} else {
					return (T) object;
				}
			}
			break;
		}

		// Handle object
		if (formalType == Object.class) {
			return (T) luaState.getProxy(index);
		}

		// Unsupported conversion
		throw new ClassCastException(String.format("cannot convert %s to %s",
				luaState.typeName(index), formalType.getCanonicalName()));
	}

	@SuppressWarnings("unchecked")
	@Override
	public void convertJavaObject(LuaState luaState, Object object) {
		// Handle null
		if (object == null) {
			luaState.pushNil();
			return;
		}

		// Handle known Java types
		JavaObjectConverter<Object> javaObjectConverter = (JavaObjectConverter<Object>) JAVA_OBJECT_CONVERTERS
				.get(object.getClass());
		if (javaObjectConverter != null) {
			javaObjectConverter.convert(luaState, object);
			return;
		}
		if (object instanceof JavaFunction) {
			luaState.pushJavaFunction((JavaFunction) object);
			return;
		}
		if (object instanceof LuaValueProxy) {
			LuaValueProxy luaValueProxy = (LuaValueProxy) object;
			if (!luaValueProxy.getLuaState().equals(luaState)) {
				throw new IllegalArgumentException(
						"Lua value proxy is from a different Lua state");
			}
			luaValueProxy.pushValue();
			return;
		}

		// Push as is
		luaState.pushJavaObjectRaw(object);
	}

	// -- Nested types
	/**
	 * Converts Lua values.
	 */
	private interface LuaValueConverter<T> {
		/**
		 * Converts a Lua value to a Java object.
		 */
		public T convert(LuaState luaState, int index);
	}

	/**
	 * Converts Java object.
	 */
	private interface JavaObjectConverter<T> {
		/**
		 * Converts a Java object to a Lua value.
		 */
		public void convert(LuaState luaState, T object);
	}
}
