/*
 * 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.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.common.utils.Stack;

/**
 * JSON.
 * 
 * @author qian.lei
 */

public class JSON
{
	public static final char LBRACE = '{', RBRACE = '}';

	public static final char LSQUARE = '[', RSQUARE = ']';

	public static final char COMMA = ',', COLON = ':', QUOTE = '"';

	public static final String NULL = "null";

	static final JSONConverter DEFAULT_CONVERTER = new GenericJSONConverter();

	// state.
	public static final byte END = 0, START = 1, OBJECT_ITEM = 2, OBJECT_VALUE = 3, ARRAY_ITEM = 4;

	private static class Entry
	{
		byte state;
		Object value;
		Entry(byte s, Object v){ state = s; value = v; }
	}

	private JSON(){}

	/**
	 * json string.
	 * 
	 * @param obj object.
	 * @return json string.
	 * @throws IOException.
	 */
	public static String json(Object obj) throws IOException
	{
		if( obj == null ) return NULL;
		StringWriter sw = new StringWriter();
		try
		{
			json(obj, sw);
			return sw.getBuffer().toString();
		}
		finally{ sw.close(); }
	}

	/**
	 * write json.
	 * 
	 * @param obj object.
	 * @param writer writer.
	 * @throws IOException.
	 */
	public static void json(Object obj, Writer writer) throws IOException
    {
	    json(obj, writer, false);
    }
	
	public static void json(Object obj, Writer writer, boolean writeClass) throws IOException
	{
		if( obj == null )
			writer.write(NULL);
		else
			json(obj, new JSONWriter(writer), writeClass);
	}

	/**
	 * json string.
	 * 
	 * @param obj object.
	 * @param properties property name array.
	 * @return json string.
	 * @throws IOException.
	 */
	public static String json(Object obj, String[] properties) throws IOException
	{
		if( obj == null ) return NULL;
		StringWriter sw = new StringWriter();
		try
		{
			json(obj, properties, sw);
			return sw.getBuffer().toString();
		}
		finally{ sw.close(); }
	}
	
	public static void json(Object obj, final String[] properties, Writer writer) throws IOException
    {
	    json(obj, properties, writer, false);
    }

	/**
	 * write json.
	 * 
	 * @param obj object.
	 * @param properties property name array.
	 * @param writer writer.
	 * @throws IOException.
	 */
	public static void json(Object obj, final String[] properties, Writer writer, boolean writeClass) throws IOException
	{
		if( obj == null )
			writer.write(NULL);
		else
			json(obj, properties, new JSONWriter(writer), writeClass);
	}

	private static void json(Object obj, JSONWriter jb, boolean writeClass) throws IOException
	{
		if( obj == null )
			jb.valueNull();
		else
			DEFAULT_CONVERTER.writeValue(obj, jb, writeClass);
	}

	private static void json(Object obj, String[] properties, JSONWriter jb, boolean writeClass) throws IOException
	{
		if( obj == null )
		{
			jb.valueNull();
		}
		else
		{
			Wrapper wrapper = Wrapper.getWrapper(obj.getClass());

			Object value;
			jb.objectBegin();
			for( String prop : properties )
			{
				jb.objectItem(prop);
				value = wrapper.getPropertyValue(obj, prop);
				if( value == null )
					jb.valueNull();
				else
					DEFAULT_CONVERTER.writeValue(value, jb, writeClass);
			}
			jb.objectEnd();
		}
	}

	/**
	 * parse json.
	 * 
	 * @param json json source.
	 * @return JSONObject or JSONArray or Boolean or Long or Double or String or null
	 * @throws ParseException
	 */
	public static Object parse(String json) throws ParseException
	{
		StringReader reader = new StringReader(json);
		try{ return parse(reader); }
		catch(IOException e){ throw new ParseException(e.getMessage()); }
		finally{ reader.close(); }
	}

	/**
	 * parse json.
	 * 
	 * @param reader reader.
	 * @return JSONObject or JSONArray or Boolean or Long or Double or String or null
	 * @throws IOException
	 * @throws ParseException
	 */
	public static Object parse(Reader reader) throws IOException, ParseException
	{
		return parse(reader, JSONToken.ANY);
	}

	/**
	 * parse json.
	 * 
	 * @param json json string.
	 * @param type target type.
	 * @return result.
	 * @throws ParseException
	 */
	public static <T> T parse(String json, Class<T> type) throws ParseException
	{
		StringReader reader = new StringReader(json);
		try{ return parse(reader, type); }
		catch(IOException e){ throw new ParseException(e.getMessage()); }
		finally{ reader.close(); }
	}

	/**
	 * parse json
	 * 
	 * @param reader json source.
	 * @param type target type.
	 * @return result.
	 * @throws IOException
	 * @throws ParseException
	 */
	@SuppressWarnings("unchecked")
	public static <T> T parse(Reader reader, Class<T> type) throws IOException, ParseException
	{
		return (T)parse(reader, new J2oVisitor(type, DEFAULT_CONVERTER), JSONToken.ANY);
	}

	/**
	 * parse json.
	 * 
	 * @param json json string.
	 * @param types target type array.
	 * @return result.
	 * @throws ParseException
	 */
	public static Object[] parse(String json, Class<?>[] types) throws ParseException
	{
		StringReader reader = new StringReader(json);
		try{ return (Object[])parse(reader, types); }
		catch(IOException e){ throw new ParseException(e.getMessage()); }
		finally{ reader.close(); }
	}

	/**
	 * parse json.
	 * 
	 * @param reader json source.
	 * @param types target type array.
	 * @return result.
	 * @throws IOException
	 * @throws ParseException
	 */
	public static Object[] parse(Reader reader, Class<?>[] types) throws IOException, ParseException
	{
		return (Object[])parse(reader, new J2oVisitor(types, DEFAULT_CONVERTER), JSONToken.LSQUARE);
	}

	/**
	 * parse json.
	 * 
	 * @param json json string.
	 * @param handler handler.
	 * @return result.
	 * @throws ParseException
	 */
	public static Object parse(String json, JSONVisitor handler) throws ParseException
	{
		StringReader reader = new StringReader(json);
		try{ return parse(reader, handler); }
		catch(IOException e){ throw new ParseException(e.getMessage()); }
		finally{ reader.close(); }
	}

	/**
	 * parse json.
	 * 
	 * @param reader json source.
	 * @param handler handler.
	 * @return resule.
	 * @throws IOException
	 * @throws ParseException
	 */
	public static Object parse(Reader reader, JSONVisitor handler) throws IOException, ParseException
	{
		return parse(reader, handler, JSONToken.ANY);
	}

	private static Object parse(Reader reader, int expect) throws IOException, ParseException
	{
		JSONReader jr = new JSONReader(reader);
		JSONToken token = jr.nextToken(expect);

		byte state = START;
		Object value = null, tmp;
		Stack<Entry> stack = new Stack<Entry>();

		do
		{
			switch( state )
			{
				case END:
					throw new ParseException("JSON source format error.");
				case START:
				{
					switch( token.type )
					{
						case JSONToken.NULL: case JSONToken.BOOL: case JSONToken.INT: case JSONToken.FLOAT: case JSONToken.STRING:
						{
							state = END;
							value = token.value;
							break;
						}
						case JSONToken.LSQUARE:
						{
							state = ARRAY_ITEM;
							value = new JSONArray();
							break;
						}
						case JSONToken.LBRACE:
						{
							state = OBJECT_ITEM;
							value = new JSONObject();
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case ARRAY_ITEM:
				{
					switch( token.type )
					{
						case JSONToken.COMMA:
							break;
						case JSONToken.NULL: case JSONToken.BOOL: case JSONToken.INT: case JSONToken.FLOAT: case JSONToken.STRING:
						{
							((JSONArray)value).add(token.value);
							break;
						}
						case JSONToken.RSQUARE: // end of array.
						{
							if( stack.isEmpty() )
							{
								state = END;
							}
							else
							{
								Entry entry = stack.pop();
								state = entry.state;
								value = entry.value;
							}
							break;
						}
						case JSONToken.LSQUARE: // array begin.
						{
							tmp = new JSONArray();
							((JSONArray)value).add(tmp);
							stack.push(new Entry(state, value));

							state = ARRAY_ITEM;
							value = tmp;
							break;
						}
						case JSONToken.LBRACE: // object begin.
						{
							tmp = new JSONObject();
							((JSONArray)value).add(tmp);
							stack.push(new Entry(state, value));

							state = OBJECT_ITEM;
							value = tmp;
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or ',' or ']' or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case OBJECT_ITEM:
				{
					switch( token.type )
					{
						case JSONToken.COMMA:
							break;
						case JSONToken.IDENT: // item name.
						{
							stack.push(new Entry(OBJECT_ITEM, (String)token.value));
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.NULL:
						{
							stack.push(new Entry(OBJECT_ITEM, "null"));
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.BOOL: case JSONToken.INT: case JSONToken.FLOAT: case JSONToken.STRING:
						{
							stack.push(new Entry(OBJECT_ITEM, token.value.toString()));
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.RBRACE: // end of object.
						{
							if( stack.isEmpty() )
							{
								state = END;
							}
							else
							{
								Entry entry = stack.pop();
								state = entry.state;
								value = entry.value;
							}
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ IDENT or VALUE or ',' or '}' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case OBJECT_VALUE:
				{
					switch( token.type )
					{
						case JSONToken.COLON:
							break;
						case JSONToken.NULL: case JSONToken.BOOL: case JSONToken.INT: case JSONToken.FLOAT: case JSONToken.STRING:
						{
							((JSONObject)value).put((String)stack.pop().value, token.value);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.LSQUARE: // array begin.
						{
							tmp = new JSONArray();
							((JSONObject)value).put((String)stack.pop().value, tmp);
							stack.push(new Entry(OBJECT_ITEM, value));

							state = ARRAY_ITEM;
							value = tmp;
							break;
						}
						case JSONToken.LBRACE: // object begin.
						{
							tmp = new JSONObject();
							((JSONObject)value).put((String)stack.pop().value, tmp);
							stack.push(new Entry(OBJECT_ITEM, value));

							state = OBJECT_ITEM;
							value = tmp;
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				default:
					throw new ParseException("Unexcepted state.");
			}
		}
		while( ( token = jr.nextToken() ) != null );
		stack.clear();
		return value;
	}

	private static Object parse(Reader reader, JSONVisitor handler, int expect) throws IOException, ParseException
	{
		JSONReader jr = new JSONReader(reader);
		JSONToken token = jr.nextToken(expect);

		Object value = null;
		int state = START, index = 0;
		Stack<int[]> states = new Stack<int[]>();
		boolean pv = false;

		handler.begin();
		do
		{
			switch( state )
			{
				case END:
					throw new ParseException("JSON source format error.");
				case START:
				{
					switch( token.type )
					{
						case JSONToken.NULL:
						{
							value = token.value;
							state = END;
							pv = true;
							break;
						}
						case JSONToken.BOOL:
						{
							value = token.value;
							state = END;
							pv = true;
							break;
						}
						case JSONToken.INT:
						{
							value = token.value;
							state = END;
							pv = true;
							break;
						}
						case JSONToken.FLOAT:
						{
							value = token.value;
							state = END;
							pv = true;
							break;
						}
						case JSONToken.STRING:
						{
							value = token.value;
							state = END;
							pv = true;
							break;
						}
						case JSONToken.LSQUARE:
						{
							handler.arrayBegin();
							state = ARRAY_ITEM;
							break;
						}
						case JSONToken.LBRACE:
						{
							handler.objectBegin();
							state = OBJECT_ITEM;
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case ARRAY_ITEM:
				{
					switch( token.type )
					{
						case JSONToken.COMMA:
							break;
						case JSONToken.NULL:
						{
							handler.arrayItem(index++);
							handler.arrayItemValue(index, token.value, true);
							break;
						}
						case JSONToken.BOOL:
						{
							handler.arrayItem(index++);
							handler.arrayItemValue(index, token.value, true);
							break;
						}
						case JSONToken.INT:
						{
							handler.arrayItem(index++);
							handler.arrayItemValue(index, token.value, true);
							break;
						}
						case JSONToken.FLOAT:
						{
							handler.arrayItem(index++);
							handler.arrayItemValue(index, token.value, true);
							break;
						}
						case JSONToken.STRING:
						{
							handler.arrayItem(index++);
							handler.arrayItemValue(index, token.value, true);
							break;
						}
						case JSONToken.LSQUARE:
						{
							handler.arrayItem(index++);
							states.push(new int[]{state, index});

							index = 0;
							state = ARRAY_ITEM;
							handler.arrayBegin();
							break;
						}
						case JSONToken.LBRACE:
						{
							handler.arrayItem(index++);
							states.push(new int[]{state, index});

							index = 0;
							state = OBJECT_ITEM;
							handler.objectBegin();
							break;
						}
						case JSONToken.RSQUARE:
						{
							if( states.isEmpty() )
							{
								value = handler.arrayEnd(index);
								state = END;
							}
							else
							{
								value = handler.arrayEnd(index);
								int[] tmp = states.pop();
								state = tmp[0];
								index = tmp[1];

								switch( state )
								{
									case ARRAY_ITEM:
									{
										handler.arrayItemValue(index, value, false);
										break;
									}
									case OBJECT_ITEM:
									{
										handler.objectItemValue(value, false);
										break;
									}
								}
							}
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or ',' or ']' or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case OBJECT_ITEM:
				{
					switch( token.type )
					{
						case JSONToken.COMMA:
							break;
						case JSONToken.IDENT:
						{
							handler.objectItem((String)token.value);
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.NULL:
						{
							handler.objectItem("null");
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.BOOL: case JSONToken.INT: case JSONToken.FLOAT: case JSONToken.STRING:
						{
							handler.objectItem(token.value.toString());
							state = OBJECT_VALUE;
							break;
						}
						case JSONToken.RBRACE:
						{
							if( states.isEmpty() )
							{
								value = handler.objectEnd(index);
								state = END;
							}
							else
							{
								value = handler.objectEnd(index);
								int[] tmp = states.pop();
								state = tmp[0];
								index = tmp[1];

								switch( state )
								{
									case ARRAY_ITEM:
									{
										handler.arrayItemValue(index, value, false);
										break;
									}
									case OBJECT_ITEM:
									{
										handler.objectItemValue(value, false);
										break;
									}
								}
							}
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ IDENT or VALUE or ',' or '}' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				case OBJECT_VALUE:
				{
					switch( token.type )
					{
						case JSONToken.COLON:
							break;
						case JSONToken.NULL:
						{
							handler.objectItemValue(token.value, true);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.BOOL:
						{
							handler.objectItemValue(token.value, true);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.INT:
						{
							handler.objectItemValue(token.value, true);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.FLOAT:
						{
							handler.objectItemValue(token.value, true);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.STRING:
						{
							handler.objectItemValue(token.value, true);
							state = OBJECT_ITEM;
							break;
						}
						case JSONToken.LSQUARE:
						{
							states.push(new int[]{OBJECT_ITEM, index});

							index = 0;
							state = ARRAY_ITEM;
							handler.arrayBegin();
							break;
						}
						case JSONToken.LBRACE:
						{
							states.push(new int[]{OBJECT_ITEM, index});

							index = 0;
							state = OBJECT_ITEM;
							handler.objectBegin();
							break;
						}
						default:
							throw new ParseException("Unexcepted token expect [ VALUE or '[' or '{' ] get '" + JSONToken.token2string(token.type) + "'");
					}
					break;
				}
				default:
					throw new ParseException("Unexcepted state.");
			}
		}
		while( ( token = jr.nextToken() ) != null );
		states.clear();
		return handler.end(value, pv);
	}
}