/*
 * 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.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.common.io.Bytes;

public class GenericJSONConverter implements JSONConverter
{
	private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
	
	protected interface Encoder{ void encode(Object obj, JSONWriter jb) throws IOException; }

	protected interface Decoder{ Object decode(Object jv) throws IOException; }

	private static final Map<Class<?>, Encoder> GlobalEncoderMap = new HashMap<Class<?>, Encoder>();

	private static final Map<Class<?>, Decoder> GlobalDecoderMap = new HashMap<Class<?>, Decoder>();

	@SuppressWarnings("unchecked")
	public void writeValue(Object obj, JSONWriter jb, boolean writeClass) throws IOException
	{
		if (obj == null) {
			jb.valueNull();
			return;
		}
		Class<?> c = obj.getClass();
		Encoder encoder = GlobalEncoderMap.get(c);

		if( encoder != null )
		{
			encoder.encode(obj, jb);
		}
		else if( obj instanceof JSONNode )
		{
			((JSONNode)obj).writeJSON(this, jb, writeClass);
		}
		else if( c.isEnum() )
		{
			jb.valueString(((Enum<?>)obj).name());
		}
		else if( c.isArray() )
		{
			int len = Array.getLength(obj);
			jb.arrayBegin();
			for(int i=0;i<len;i++)
				writeValue(Array.get(obj, i), jb, writeClass);
			jb.arrayEnd();
		}
		else if( Map.class.isAssignableFrom(c) )
		{
			Object key, value;
			jb.objectBegin();
			for( Map.Entry<Object, Object> entry : ((Map<Object, Object>)obj).entrySet() )
			{
				key = entry.getKey();
				if( key == null )
					continue;
				jb.objectItem(key.toString());

				value = entry.getValue();
				if( value == null )
					jb.valueNull();
				else
					writeValue(value, jb, writeClass);
			}
			jb.objectEnd();
		}
		else if( Collection.class.isAssignableFrom(c) )
		{
			jb.arrayBegin();
			for( Object item : (Collection<Object>)obj )
			{
				if( item == null )
					jb.valueNull();
				else
					writeValue(item, jb, writeClass);
			}
			jb.arrayEnd();
		}
		else
		{
			jb.objectBegin();
			
			Wrapper w = Wrapper.getWrapper(c);
			String pns[] = w.getPropertyNames();

			for( String pn : pns )
			{
				if ((obj instanceof Throwable) && (
						"localizedMessage".equals(pn) 
						|| "cause".equals(pn) 
						|| "stackTrace".equals(pn))) {
					continue;
				}
				
				jb.objectItem(pn);

				Object value = w.getPropertyValue(obj,pn);
				if( value == null || value == obj)
					jb.valueNull();
				else
					writeValue(value, jb, writeClass);
			}
			if (writeClass) {
			    jb.objectItem(JSONVisitor.CLASS_PROPERTY);
			    writeValue(obj.getClass().getName(), jb, writeClass);
			}
			jb.objectEnd();
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Object readValue(Class<?> c, Object jv) throws IOException
	{
		if (jv == null) {
			return null;
		}
		Decoder decoder = GlobalDecoderMap.get(c);
		if( decoder != null ) {
			return decoder.decode(jv);
		}
		if (c.isEnum()) {
			return Enum.valueOf((Class<Enum>)c, String.valueOf(jv));
		}
		return jv;
	}

	static
	{
		// init encoder map.
		Encoder e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueBoolean((Boolean)obj);
			}
		};
		GlobalEncoderMap.put(boolean.class, e);
		GlobalEncoderMap.put(Boolean.class, e);

		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueInt(((Number)obj).intValue());
			}
		};
		GlobalEncoderMap.put(int.class, e);
		GlobalEncoderMap.put(Integer.class, e);
		GlobalEncoderMap.put(short.class, e);
		GlobalEncoderMap.put(Short.class, e);
		GlobalEncoderMap.put(byte.class, e);
		GlobalEncoderMap.put(Byte.class, e);
		GlobalEncoderMap.put(AtomicInteger.class, e);
		
		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueString(Character.toString((Character)obj));
			}
		};
		GlobalEncoderMap.put(char.class, e);
		GlobalEncoderMap.put(Character.class, e);
		
		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueLong(((Number)obj).longValue());
			}
		};
		GlobalEncoderMap.put(long.class, e);
		GlobalEncoderMap.put(Long.class, e);
		GlobalEncoderMap.put(AtomicLong.class, e);
		GlobalEncoderMap.put(BigInteger.class, e);

		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueFloat(((Number)obj).floatValue());
			}
		};
		GlobalEncoderMap.put(float.class, e);
		GlobalEncoderMap.put(Float.class, e);

		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueDouble(((Number)obj).doubleValue());
			}
		};
		GlobalEncoderMap.put(double.class, e);
		GlobalEncoderMap.put(Double.class, e);
		GlobalEncoderMap.put(BigDecimal.class, e);

		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueString(obj.toString());
			}
		};
		GlobalEncoderMap.put(String.class, e);
		GlobalEncoderMap.put(StringBuilder.class, e);
		GlobalEncoderMap.put(StringBuffer.class, e);

		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueString(Bytes.bytes2base64((byte[])obj));
			}
		};
		GlobalEncoderMap.put(byte[].class, e);
		
		e = new Encoder(){
			public void encode(Object obj, JSONWriter jb) throws IOException
			{
				jb.valueString(new SimpleDateFormat(DATE_FORMAT).format((Date)obj));
			}
		};
		GlobalEncoderMap.put(Date.class, e);

		// init decoder map.
		Decoder d = new Decoder(){
			public Object decode(Object jv){ 
				return jv.toString(); 
			} 
		};
		GlobalDecoderMap.put(String.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Boolean ) return ((Boolean)jv).booleanValue();
				return false;
			}
		};
		GlobalDecoderMap.put(boolean.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Boolean ) return (Boolean)jv;
				return (Boolean)null;
			}
		};
		GlobalDecoderMap.put(Boolean.class, d);
		
		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof String && ((String)jv).length() > 0) return ((String)jv).charAt(0);
				return (char)0;
			}
		};
		GlobalDecoderMap.put(char.class, d);
		
		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof String && ((String)jv).length() > 0) return ((String)jv).charAt(0);
				return (Character)null;
			}
		};
		GlobalDecoderMap.put(Character.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).intValue();
				return 0;
			}
		};
		GlobalDecoderMap.put(int.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return Integer.valueOf(((Number)jv).intValue());
				return (Integer)null;
			}
		};
		GlobalDecoderMap.put(Integer.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).shortValue();
				return (short)0;
			}
		};
		GlobalDecoderMap.put(short.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return Short.valueOf(((Number)jv).shortValue());
				return (Short)null;
			}
		};
		GlobalDecoderMap.put(Short.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).longValue();
				return (long)0;
			}
		};
		GlobalDecoderMap.put(long.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return Long.valueOf(((Number)jv).longValue());
				return (Long)null;
			}
		};
		GlobalDecoderMap.put(Long.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).floatValue();
				return (float)0;
			}
		};
		GlobalDecoderMap.put(float.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return new Float(((Number)jv).floatValue());
				return (Float)null;
			}
		};
		GlobalDecoderMap.put(Float.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).doubleValue();
				return (double)0;
			}
		};
		GlobalDecoderMap.put(double.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return new Double(((Number)jv).doubleValue());
				return (Double)null;
			}
		};
		GlobalDecoderMap.put(Double.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return ((Number)jv).byteValue();
				return (byte)0;
			}
		};
		GlobalDecoderMap.put(byte.class, d);

		d = new Decoder(){
			public Object decode(Object jv)
			{
				if( jv instanceof Number ) return Byte.valueOf(((Number)jv).byteValue());
				return (Byte)null;
			}
		};
		GlobalDecoderMap.put(Byte.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof String ) return Bytes.base642bytes((String)jv);
				return (byte[])null;
			}
		};
		GlobalDecoderMap.put(byte[].class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException{ return new StringBuilder(jv.toString()); }
		};
		GlobalDecoderMap.put(StringBuilder.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException{ return new StringBuffer(jv.toString()); }
		};
		GlobalDecoderMap.put(StringBuffer.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof Number ) return BigInteger.valueOf(((Number)jv).longValue());
				return (BigInteger)null;
			}
		};
		GlobalDecoderMap.put(BigInteger.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof Number ) return BigDecimal.valueOf(((Number)jv).doubleValue());
				return (BigDecimal)null;
			}
		};
		GlobalDecoderMap.put(BigDecimal.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof Number ) return new AtomicInteger(((Number)jv).intValue());
				return (AtomicInteger)null;
			}
		};
		GlobalDecoderMap.put(AtomicInteger.class, d);

		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof Number ) return new AtomicLong(((Number)jv).longValue());
				return (AtomicLong)null;
			}
		};
		GlobalDecoderMap.put(AtomicLong.class, d);
		
		d = new Decoder(){
			public Object decode(Object jv) throws IOException
			{
				if( jv instanceof String ) {
					try {
						return new SimpleDateFormat(DATE_FORMAT).parse((String) jv);
					} catch (ParseException e) {
						throw new IllegalArgumentException(e.getMessage(), e);
					}
				}
				if( jv instanceof Number ) 
					return new Date(((Number)jv).longValue());
				return (Date)null;
			}
		};
		GlobalDecoderMap.put(Date.class, d);
	}
}