/*
 * 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.json;

import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.common.utils.Stack;
import com.alibaba.dubbo.common.utils.StringUtils;

/**
 * JSON to Object visitor.
 * 
 * @author qian.lei.
 */

class J2oVisitor implements JSONVisitor
{
	public static final boolean[] EMPTY_BOOL_ARRAY = new boolean[0];

	public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

	public static final char[] EMPTY_CHAR_ARRAY = new char[0];

	public static final short[] EMPTY_SHORT_ARRAY = new short[0];

	public static final int[] EMPTY_INT_ARRAY = new int[0];

	public static final long[] EMPTY_LONG_ARRAY = new long[0];

	public static final float[] EMPTY_FLOAT_ARRAY = new float[0];

	public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];

	public static final String[] EMPTY_STRING_ARRAY = new String[0];

	private Class<?>[] mTypes;

	private Class<?> mType = Object[].class;

	private Object mValue;

	private Wrapper mWrapper;

	private JSONConverter mConverter;

	private Stack<Object> mStack = new Stack<Object>();

	J2oVisitor(Class<?> type, JSONConverter jc)
	{
		mType = type;
		mConverter = jc;
	}

	J2oVisitor(Class<?>[] types, JSONConverter jc)
	{
		mTypes = types;
		mConverter = jc;
	}

	public void begin()
	{}

	public Object end(Object obj, boolean isValue) throws ParseException
	{
		mStack.clear();
		try {
			return mConverter.readValue(mType, obj);
		} catch (IOException e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}

	public void objectBegin() throws ParseException
	{
		mStack.push(mValue);
		mStack.push(mType);
		mStack.push(mWrapper);

		if( mType == Object.class || Map.class.isAssignableFrom(mType) )
		{
			if (! mType.isInterface() && mType != Object.class) {
				try {
					mValue = mType.newInstance();
				} catch (Exception e) {
					throw new IllegalStateException(e.getMessage(), e);
				}
			} else if (mType == ConcurrentMap.class) {
				mValue = new ConcurrentHashMap<String, Object>();
			} else {
				mValue = new HashMap<String, Object>();
			}
			mWrapper = null;
		} else {
			try {
				mValue = mType.newInstance();
				mWrapper = Wrapper.getWrapper(mType);
			} catch(IllegalAccessException e){ 
				throw new ParseException(StringUtils.toString(e)); 
			} catch(InstantiationException e){ 
				throw new ParseException(StringUtils.toString(e)); 
			}
		}
	}

	public Object objectEnd(int count)
	{
		Object ret = mValue;
		mWrapper = (Wrapper)mStack.pop();
		mType = (Class<?>)mStack.pop();
		mValue = mStack.pop();
		return ret;
	}

	public void objectItem(String name)
	{
		mStack.push(name); // push name.
		mType = ( mWrapper == null ? Object.class : mWrapper.getPropertyType(name) );
	}

	@SuppressWarnings("unchecked")
	public void objectItemValue(Object obj, boolean isValue) throws ParseException
	{
		String name = (String)mStack.pop();  // pop name.
		if( mWrapper == null )
		{
			((Map<String, Object>)mValue).put(name, obj);
		}
		else
		{
			if( mType != null )
			{
				if( isValue && obj != null )
				{
					try
					{
						obj = mConverter.readValue(mType, obj);
					}
					catch(IOException e)
					{
						throw new ParseException(StringUtils.toString(e));
					}
				}
				if (mValue instanceof Throwable && "message".equals(name)) {
					try {
						Field field = Throwable.class.getDeclaredField("detailMessage");
						if (! field.isAccessible()) {
							field.setAccessible(true);
						}
						field.set(mValue, obj);
					} catch (NoSuchFieldException e) {
						throw new ParseException(StringUtils.toString(e));
					} catch (IllegalAccessException e) {
						throw new ParseException(StringUtils.toString(e));
					}
				} else if (! CLASS_PROPERTY.equals(name)) {
					mWrapper.setPropertyValue(mValue, name, obj);
				}
			}
		}
	}

	public void arrayBegin() throws ParseException
	{
		mStack.push(mType);

		if( mType.isArray() )
			mType = mType.getComponentType();
		else if( mType == Object.class || Collection.class.isAssignableFrom(mType) )
			mType = Object.class;
		else
			throw new ParseException("Convert error, can not load json array data into class [" + mType.getName() + "].");
	}

	@SuppressWarnings("unchecked")
	public Object arrayEnd(int count) throws ParseException
	{
		Object ret;
		mType = (Class<?>)mStack.get(-1-count);

		if( mType.isArray() )
		{
			ret = toArray(mType.getComponentType(), mStack, count);
		}
		else
		{
			Collection<Object> items;
			if( mType == Object.class || Collection.class.isAssignableFrom(mType)) {
				if (! mType.isInterface() && mType != Object.class) {
					try {
						items = (Collection<Object>) mType.newInstance();
					} catch (Exception e) {
						throw new IllegalStateException(e.getMessage(), e);
					}
				} else if (mType.isAssignableFrom(ArrayList.class)) { // List
					items = new ArrayList<Object>(count);
				} else if (mType.isAssignableFrom(HashSet.class)) { // Set
					items = new HashSet<Object>(count);
				} else if (mType.isAssignableFrom(LinkedList.class)) { // Queue
					items = new LinkedList<Object>();
				} else { // Other
					items = new ArrayList<Object>(count);
				}
			} else {
				throw new ParseException("Convert error, can not load json array data into class [" + mType.getName() + "].");
			}
			for(int i=0;i<count;i++)
				items.add(mStack.remove(i-count));
			ret = items;
		}
		mStack.pop();
		return ret;
	}

	public void arrayItem(int index) throws ParseException
	{
		if( mTypes != null && mStack.size() == index+1 )
		{
			if( index < mTypes.length )
				mType = mTypes[index];
			else
				throw new ParseException("Can not load json array data into [" + name(mTypes) + "].");
		}
	}

	public void arrayItemValue(int index, Object obj, boolean isValue) throws ParseException
	{
		if( isValue && obj != null )
		{
			try
			{
				obj = mConverter.readValue(mType, obj);
			}
			catch(IOException e)
			{
				throw new ParseException(e.getMessage());
			}
		}

		mStack.push(obj);
	}

	private static Object toArray(Class<?> c, Stack<Object> list, int len) throws ParseException
	{
		if( c == String.class )
		{
			if( len == 0 )
			{
				return EMPTY_STRING_ARRAY;
			}
			else
			{
				Object o;
				String ss[] = new String[len];
				for(int i=len-1;i>=0;i--)
				{
					o = list.pop();
					ss[i] = ( o == null ? null : o.toString() );
				}
				return ss;
			}
		}
		if( c == boolean.class )
		{
			if( len == 0 ) return EMPTY_BOOL_ARRAY;
			Object o;
			boolean[] ret = new boolean[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Boolean )
					ret[i] = ((Boolean)o).booleanValue();
			}
			return ret;
		}
		if( c == int.class )
		{
			if( len == 0 ) return EMPTY_INT_ARRAY;
			Object o;
			int[] ret = new int[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).intValue();
			}
			return ret;
		}
		if( c == long.class )
		{
			if( len == 0 ) return EMPTY_LONG_ARRAY;
			Object o;
			long[] ret = new long[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).longValue();
			}
			return ret;
		}
		if( c == float.class )
		{
			if( len == 0 ) return EMPTY_FLOAT_ARRAY;
			Object o;
			float[] ret = new float[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).floatValue();
			}
			return ret;
		}
		if( c == double.class )
		{
			if( len == 0 ) return EMPTY_DOUBLE_ARRAY;
			Object o;
			double[] ret = new double[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).doubleValue();
			}
			return ret;
		}
		if( c == byte.class )
		{
			if( len == 0 ) return EMPTY_BYTE_ARRAY;
			Object o;
			byte[] ret = new byte[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).byteValue();
			}
			return ret;
		}
		if( c == char.class )
		{
			if( len == 0 ) return EMPTY_CHAR_ARRAY;
			Object o;
			char[] ret = new char[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Character )
					ret[i] = ((Character)o).charValue();
			}
			return ret;
		}
		if( c == short.class )
		{
			if( len == 0 ) return EMPTY_SHORT_ARRAY;
			Object o;
			short[] ret = new short[len];
			for(int i=len-1;i>=0;i--)
			{
				o = list.pop();
				if( o instanceof Number )
					ret[i] = ((Number)o).shortValue();
			}
			return ret;
		}

		Object ret = Array.newInstance(c, len);
		for(int i=len-1;i>=0;i--)
			Array.set(ret, i, list.pop());
		return ret;
	}

	private static String name(Class<?>[] types)
	{
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<types.length;i++)
		{
			if( i > 0 )
				sb.append(", ");
			sb.append(types[i].getName());
		}
		return sb.toString();
	}
}