/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Hisashi MIYASHITA - initial API and implementation
 *******************************************************************************/

package org.eclipse.actf.model.flash.as;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Class for Deserializing a string in JSON notation to a Java object. Note that
 * a property name should be quoted in JSON object notation. E.g.
 * <code>{"id":123}</code>. In this deserializer, a JSON object is
 * deserialized to an {@link ASObject} instance.
 * 
 * @see ASObject
 */
public class ASDeserializer {
	/**
	 * Token dictionary used to convert reserved words to Java constants.
	 */
	private static final Map<String, Object> tokenDic = new HashMap<String, Object>();
	/**
	 * String constant to denote JSON <code>undefined</code> value.
	 */
	private static final Object UNDEFINED = "undefined".intern();
	/**
	 * String constant to denote JSON <code>null</code> value.
	 */
	private static final Object NULL = "null".intern();

	/**
	 * Initializes the token dictionary.
	 */
	static {
		tokenDic.put("true", Boolean.valueOf(true));
		tokenDic.put("false", Boolean.valueOf(false));
		tokenDic.put("undefined", UNDEFINED);
		tokenDic.put("null", NULL);
	}

	/**
	 * Internal variable to hold cursor position in parsing. <code>0</code>
	 * means the first character of the string.
	 */
	private int idx;
	/**
	 * Internal variable to hold a string to be serialized. Set by the
	 * constructor.
	 */
	private String str;

	/**
	 * Skips a sequence of whitespace characters.
	 * 
	 * @return Cursor position after skipping. It returns <code>-1</code> if
	 *         it reaches the end of the string.
	 */
	private int skipSP() {
		while (idx < str.length()) {
			char ch = str.charAt(idx);
			switch (ch) {
			case ' ':
			case '\t':
			case '\n':
			case '\r':
				idx++;
				break;
			default:
				return idx;
			}
		}
		return -1;

	}

	/**
	 * Seatch the end of a token starts from the current cursor position.
	 * 
	 * @return Cursor position after search. It points the next character to the
	 *         end of given token.
	 */
	private int getTokenEndIdx() {
		int idx2 = idx;
		while (idx2 < str.length()) {
			char ch = str.charAt(idx2);
			switch (ch) {
			case ' ':
			case '\t':
			case '\n':
			case '\r':
			case ',':
			case ':':
			case '}':
			case ']':
				return idx2;

			default:
				idx2++;
			}
		}
		return idx2;
	}

	/**
	 * Deserializes a JSON string to Java string. Note that JSON string should
	 * be quoted as <code>"Hello, Java"</code>. This method is internally
	 * called from {@link #deserialize()}.
	 * 
	 * @return Deserialized Java string.
	 * @throws IllegalArgumentException
	 *             when given JSON string is ill-formed.
	 */
	private String deserializeString() {
		StringBuffer ret = new StringBuffer();
		idx++;
		while (idx < str.length()) {
			char ch = str.charAt(idx);
			switch (ch) {
			case '"':
				idx++;
				return ret.toString();
			case '\\':
				idx++;
				if (idx == str.length()) {
					throw new IllegalArgumentException(
							"Abnormal end of the string:" + str);
				}
				ret.append(str.charAt(idx));
				idx++;
				break;
			default:
				ret.append(ch);
				idx++;
			}
		}
		throw new IllegalArgumentException("Invalid String:" + str);
	}

	/**
	 * Deserializes a JSON array string to Java array. This method is internally
	 * called from {@link #deserialize()}.
	 * 
	 * @return Deserialized Java array.
	 * @throws IllegalArgumentException
	 *             when given JSON string is ill-formed.
	 */
	private Object[] deserializeArray() {
		idx++;
		ArrayList<Object> ret = new ArrayList<Object>();
		while (idx < str.length()) {
			skipSP();
			char ch = str.charAt(idx);
			if (ch == ']') {
				idx++;
				return ret.toArray(new Object[ret.size()]);
			} else {
				ret.add(deserialize());
			}
			skipSP();
			ch = str.charAt(idx);
			if (ch == ']') {
				idx++;
				return ret.toArray(new Object[ret.size()]);
			}
			if (ch != ',') {
				throw new IllegalArgumentException("Missing ',':" + str);
			}
			idx++;
		}
		throw new IllegalArgumentException("Abnormal end of the array:" + str);
	}

	/**
	 * Deserializes a JSON object string to {@link ASObject} instance. This
	 * method is internally called from {@link #deserialize()}.
	 * 
	 * @return Deserialized {@link ASObject} instance.
	 * @throws IllegalArgumentException
	 *             when given JSON string is ill-formed.
	 */
	private ASObject deserializeASObject() {
		idx++;
		ASObject ret = new ASObject();
		while (idx < str.length()) {
			skipSP();
			char ch = str.charAt(idx);
			if (ch == '}') {
				idx++;
				return ret;
			} else {
				String prop = deserializeString();
				skipSP();
				if (str.charAt(idx) != ':') {
					throw new IllegalArgumentException("Missing ':':" + str);
				}
				idx++;
				Object o = deserialize();
				ret.put(prop, o);
			}
			skipSP();
			ch = str.charAt(idx);
			if (ch == '}') {
				idx++;
				return ret;
			}
			if (str.charAt(idx) != ',') {
				throw new IllegalArgumentException("Missing ',':" + str);
			}
			idx++;
		}
		throw new IllegalArgumentException("Abnormal end of the array:" + str);
	}

	/**
	 * Deserializes a given JSON string. Especially a JSON object string is
	 * deserialized to an {@link ASObject} instance.
	 * 
	 * Note that a property name should be quoted in JSON object notation. E.g.
	 * <code>{"id":123}</code>.
	 * 
	 * @return Deserialized object.
	 * @throws IllegalArgumentException
	 *             when given JSON string is not in valid format.
	 */
	public Object deserialize() {
		int r = skipSP();
		if (r < 0)
			return null;
		char ch = str.charAt(idx);
		switch (ch) {
		case '[':
			return deserializeArray();
		case '{':
			return deserializeASObject();
		case '"':
			return deserializeString();
		default:
			int idx2 = getTokenEndIdx();
			String tok = str.substring(idx, idx2);
			Object o = tokenDic.get(tok);
			this.idx = idx2;
			if (o == NULL) {
				return null;
			}
			if (o != null) {
				return o;
			}
			try {
				int i = Integer.parseInt(tok);
				return Integer.valueOf(i);
			} catch (NumberFormatException e) {
			}
			try {
				double d = Double.parseDouble(tok);
				return new Double(d);
			} catch (NumberFormatException e) {
			}
			throw new IllegalArgumentException(tok + " is not a valid token.");
		}

	}

	/**
	 * Creates an {@link ASDeserializer} instance.
	 * 
	 * @param str
	 *            JSON string to be deserialized
	 */
	public ASDeserializer(String str) {
		this.idx = 0;
		this.str = str;
	}
}
