/*******************************************************************************
 * Copyright (c) 2005, 2006 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*


 */
package org.eclipse.jem.internal.beaninfo.common;

import java.io.*;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.regex.Pattern;

import org.eclipse.jem.internal.proxy.common.MapTypes;

 

/**
 * This is the value for a FeatureAttribute. It wrappers the true java object.
 * Use the getObject method to get the java value.
 * <p>
 * We can only represent Strings, primitives, and arrays. (Primitives will converted
 * to their wrapper class (e.g. Long), and byte, short, and int will move up to Long,
 * and float will move up to Double).  And any kind of valid array on the java BeanInfo side
 * will be converted to an Object array on the IDE side. We don't have the capability to allow more complex objects 
 * because the IDE may not have the necessary classes available to it that 
 * the BeanInfo may of had available to it. Invalid objects will be represented
 * by the singleton instance of {@link org.eclipse.jem.internal.beaninfo.common.InvalidObject}.
 * <p>
 * <b>Note:</b>
 * Class objects that are values of Feature attributes on the java BeanInfo side will be
 * converted to simple strings containing the classname when moved to the client (IDE) side.
 * That is because the classes probably will not be available on the IDE side, but can be
 * used to reconstruct the class when used back on the java vm side. 
 * @since 1.1.0
 */
public class FeatureAttributeValue implements Serializable {
	
	private transient Object value;
	private transient Object internalValue;
	private boolean implicitValue;
	private static final long serialVersionUID = 1105717634844L;
	
	/**
	 * Create the value with the given init string.
	 * <p>
	 * This is not meant to be used by clients.
	 * @param initString
	 * 
	 * @since 1.1.0
	 */
	public FeatureAttributeValue(String initString) {
		// Use the init string to create the value. This is our
		// own short-hand for this.
		if (initString.startsWith(IMPLICIT)) {
			setImplicitValue(true);
			initString = initString.substring(IMPLICIT.length());
		}
		value = parseString(initString);
	}
	
	/**
	 * This is used when customer wants to fluff one up.
	 * 
	 * 
	 * @since 1.1.0
	 */
	public FeatureAttributeValue() {
		
	}
	
	/**
	 * @return Returns the value.
	 * 
	 * @since 1.1.0
	 */
	public Object getValue() {
		return value;
	}
	
	/**
	 * Set a value.
	 * @param value The value to set.
	 * @since 1.1.0
	 */
	public void setValue(Object value) {
		this.value = value;
		this.setInternalValue(null);
	}
		
	/**
	 * Set the internal value.
	 * @param internalValue The internalValue to set.
	 * 
	 * @since 1.1.0
	 */
	public void setInternalValue(Object internalValue) {
		this.internalValue = internalValue;
	}

	/**
	 * This is the internal value. It is the <code>value</code> massaged into an easier to use form
	 * in the IDE. It will not be serialized out. It will not be reconstructed from an init string.
	 * <p> 
	 * It does not need to be used. It will be cleared if
	 * a new value is set. For example, if the value is a complicated array (because you can't have
	 * special classes in the attribute value on the BeanInfo side) the first usage of this value can
	 * be translated into an easier form to use, such as a map.
	 * 
	 * @return Returns the internalValue.
	 * 
	 * @since 1.1.0
	 */
	public Object getInternalValue() {
		return internalValue;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		if (value == null)
			return super.toString();
		StringBuffer out = new StringBuffer(100);
		if (isImplicitValue())
			out.append(IMPLICIT);
		makeString(value, out);
		return out.toString();
	}
	

	/**
	 * Helper method to take the object and turn it into the
	 * string form that is required for EMF serialization.
	 * <p>
	 * This is used internally. It can be used for development 
	 * purposes by clients, but they would not have any real
	 * runtime need for this.
	 * <p>
	 * Output format would be (there won't be any newlines in the actual string)
	 * <pre>
	 *   String: "zxvzxv"
	 *   Number: number
	 *   Boolean: true or false
	 *   Character: 'c'
	 *   null: null
	 * 
	 *   Array: (all arrays will be turned into Object[])
	 *     [dim]{e1, e2}
	 *     [dim1][dim2]{[dim1a]{e1, e2}, [dim2a]{e3, e4}}
	 *   where en are objects that follow the pattern for single output above.
	 * 
	 *   Any invalid object (i.e. not one of the ones we handle) will be:
	 *     INV
	 * 
	 *   Arrays of invalid types (not Object, String, Number, Boolean, Character,
	 *     or primitives) will be marked as INV.
	 * </pre>
	 * @param value
	 * @return serialized form as a string.
	 * 
	 * @since 1.1.0
	 */
	public static String makeString(Object value) {
		StringBuffer out = new StringBuffer(100);
		makeString(value, out);
		return out.toString();
	}
		
	private static final Pattern QUOTE = Pattern.compile("\"");	// Pattern for searching for double-quote. Make it static so don't waste time compiling each time. //$NON-NLS-1$
	private static final String NULL = "null";	// Output string for null //$NON-NLS-1$
	private static final String INVALID = "INV";	// Invalid object flag. //$NON-NLS-1$
	private static final String IMPLICIT = "implicit,";	// Implicit flag. //$NON-NLS-1$
	
	/*
	 * Used for recursive building of the string.
	 */
	private static void makeString(Object value, StringBuffer out) {
		if (value == null)
			out.append(NULL);
		else if (value instanceof String || value instanceof Class) {
			// String: "string" or "string\"stringend" if str included a double-quote.
			out.append('"');
			// If class, turn value into the classname.
			String str = value instanceof String ? (String) value : ((Class) value).getName();
			if (str.indexOf('"') != -1) {
				// Replace double-quote with escape double-quote so we can distinquish it from the terminating double-quote.
				out.append(QUOTE.matcher(str).replaceAll("\\\\\""));	// Don't know why we need the back-slash to be doubled for replaceall, but it doesn't work otherwise. //$NON-NLS-1$
			} else
				out.append(str);
			out.append('\"');
		} else if (value instanceof Number) {
			// Will go out as either a integer number or a floating point number. 
			// When read back in it will be either a Long or a Double.
			out.append(value);
		} else if (value instanceof Boolean) {
			// It will go out as either true or false.
			out.append(value);
		} else if (value instanceof Character) {
			// Character: 'c' or '\'' if char was a quote.
			out.append('\'');
			Character c = (Character) value;
			if (c.charValue() != '\'')
				out.append(c.charValue());
			else
				out.append("\\'"); //$NON-NLS-1$
			out.append('\'');
		} else if (value.getClass().isArray()) {
			// Handle array format.
			Class type = value.getClass();
			// See if final type is a valid type.
			Class ft = type.getComponentType();
			int dims = 1;
			while (ft.isArray()) {
				dims++;
				ft = ft.getComponentType();
			}
			if (ft == Object.class || ft == String.class || ft == Boolean.class || ft == Character.class || ft.isPrimitive() || Number.class.isAssignableFrom(ft)) {
				// [length][][] {....}
				out.append('[');
				int length = Array.getLength(value); 
				out.append(length);
				out.append(']');
				while(--dims > 0) {
					out.append("[]"); //$NON-NLS-1$
				}
				out.append('{');
				for (int i=0; i < length; i++) {
					if (i != 0)
						out.append(',');
					makeString(Array.get(value, i), out);
				}
				out.append('}');
			} else
				out.append(INVALID);	// Any other kind of array is invalid.
		} else {
			out.append(INVALID);
		}
	}
	
	
	/**
	 * Helper method to take the string input from EMF serialization and turn it
	 * into an Object.
	 * <p>
	 * This is used internally. It can be used for development 
	 * purposes by clients, but they would not have any real
	 * runtime need for this.
	 * <p>
	 * The object will be an object, null, or an Object array. Any value
	 * that is invalid will be set to the {@link InvalidObject#INSTANCE} static
	 * instance.
	 * 
	 * @param input
	 * @return object decoded from the input.
	 * 
	 * @see #makeString(Object)
	 * @since 1.1.0
	 */
	public static Object parseString(String input) {
		return parseString(new StringParser(input));
	}
	
	private static class StringParser {
		private int next=0;
		private int length;
		private String input;
		
		public StringParser(String input) {
			this.input = input;
			this.length = input.length();
		}
		
		public String toString() {
			return "StringParser: \""+input+'"'; //$NON-NLS-1$
		}
		
		public void skipWhitespace() {
			while(next < length) {
				if (!Character.isWhitespace(input.charAt(next++))) {
					next--;	// Put it back as not yet read since it is not whitespace.
					break;
				}
			}
		}
		
		/**
		 * Return the next index
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public int nextIndex() {
			return next;
		}
		
		/**
		 * Get the length of the input
		 * @return input length
		 * 
		 * @since 1.1.0
		 */
		public int getLength() {
			return length;
		}
		
		
		/**
		 * Read the current character and go to next.
		 * @return current character
		 * 
		 * @since 1.1.0
		 */
		public char read() {
			return next<length ? input.charAt(next++) : 0;
		}
		
		/**
		 * Backup the parser one character.
		 * 
		 * 
		 * @since 1.1.0
		 */
		public void backup() {
			if (--next < 0)
				next = 0;
		}
		
		/**
		 * Peek at the char at the next index, but don't increment afterwards.
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public char peek() {
			return next<length ? input.charAt(next) : 0;
		}
		
		/**
		 * Have we read the last char.
		 * @return <code>true</code> if read last char.
		 * 
		 * @since 1.1.0
		 */
		public boolean atEnd() {
			return next>=length;
		}
		
		/**
		 * Reset to the given next index.
		 * @param nextIndex the next index to do a read at.
		 * 
		 * @since 1.1.0
		 */
		public void reset(int nextIndex) {
			if (nextIndex<=length)
				next = nextIndex;
			else
				next = length;
		}
		
		/**
		 * Skip the next number of chars.
		 * @param skip number of chars to skip.
		 * 
		 * @since 1.1.0
		 */
		public void skip(int skip) {
			if ((next+=skip) > length)
				next = length;
		}
		
		/**
		 * Return the string input.
		 * @return the string input
		 * 
		 * @since 1.1.0
		 */
		public String getInput() {
			return input;
		}
				
	}
	
	/*
	 * Starting a parse for an object at the given index.
	 * Return the parsed object or InvalidObject if no
	 * object or if there was an error parsing.
	 */
	private static Object parseString(StringParser parser) {
		parser.skipWhitespace();
		if (!parser.atEnd()) {
			char c = parser.read();
			switch (c) {
				case '"':
					// Start of a quoted string. Scan for closing quote, ignoring escaped quotes.
					int start = parser.nextIndex();	// Index of first char after '"'
					char[] dequoted = null;	// Used if there is an escaped quote. That is the only thing we support escape on, quotes.
					int dequoteIndex = 0;
					while (!parser.atEnd()) {
						char cc = parser.read();
						if (cc == '"') {
							// If we didn't dequote, then just do substring.
							if (dequoted == null)
								return parser.getInput().substring(start, parser.nextIndex()-1);	// next is char after '"', so end of string index is index of '"'
							else {
								// We have a dequoted string. So turn into a string.
								// Gather the last group
								int endNdx = parser.nextIndex()-1;
								parser.getInput().getChars(start, endNdx, dequoted, dequoteIndex);
								dequoteIndex+= (endNdx-start);
								return new String(dequoted, 0, dequoteIndex);
							}
						} else if (cc == '\\') {
							// We had an escape, see if next is a quote. If it is we need to strip out the '\'.
							if (parser.peek() == '"') {
								if (dequoted == null) {
									dequoted = new char[parser.getLength()];
								}
								int endNdx = parser.nextIndex()-1;
								parser.getInput().getChars(start, endNdx, dequoted, dequoteIndex);	// Get up to, but not including '\'
								dequoteIndex+= (endNdx-start);
								// Now also add in the escaped quote.
								dequoted[dequoteIndex++] = parser.read();
								start = parser.nextIndex();	// Next group is from next index.
							}
						}
					}
					break;	// If we got here, it is invalid.
					
				case '-':
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					// Possible number.
					// Scan to next non-digit, or not part of valid number.
					boolean numberComplete = false;
					boolean floatType = false;
					boolean foundE = false;
					boolean foundESign = false;
					start = parser.nextIndex()-1;	// We want to include the sign or first digit in the number.
					while (!parser.atEnd() && !numberComplete) {
						char cc = parser.read();
						switch (cc) {
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								break;	// This is good, go on.
							case '.':
								if (floatType)
									return InvalidObject.INSTANCE;	// We already found a '.', two are invalid.
								floatType = true;
								break;
							case 'e':
							case 'E':
								if (foundE)
									return InvalidObject.INSTANCE;	// We already found a 'e', two are invalid.
								foundE = true;
								floatType = true;	// An 'e' makes it a float, if not already.
								break;
							case '+':
							case '-':
								if (!foundE || foundESign) 
									return InvalidObject.INSTANCE;	// A +/- with no 'e' first is invalid. Or more than one sign.
								foundESign = true;
								break;
							default:
								// Anything else is end of number.
								parser.backup();	// Back it up so that next parse will start with this char.
								numberComplete = true;	// So we stop scanning
								break;
						}
					}
					try {
						if (!floatType)
							return Long.valueOf(parser.getInput().substring(start, parser.nextIndex()));
						else
							return Double.valueOf(parser.getInput().substring(start, parser.nextIndex()));
					} catch (NumberFormatException e) {
					}
					break; // If we got here, it is invalid.
					
				case 't':
				case 'T':
				case 'f':
				case 'F':
					// Possible boolean.
					if (parser.getInput().regionMatches(true, parser.nextIndex()-1, "true", 0, 4)) { //$NON-NLS-1$
						parser.skip(3);	// Skip over rest of string.
						return Boolean.TRUE;
					} else if (parser.getInput().regionMatches(true, parser.nextIndex()-1, "false", 0, 5)) { //$NON-NLS-1$
						parser.skip(4);	// Skip over rest of string.
						return Boolean.FALSE;						
					}
					break; // If we got here, it is invalid.
					
				case '\'':
					// Possible character
					char cc = parser.read();
					// We really only support '\\' and '\'' anything else will be treated as ignore '\' because we don't know handle full escapes.
					if (cc == '\\')
						cc = parser.read();	// Get what's after it.
					else if (cc == '\'')
						break;	// '' is invalid.
					if (parser.peek() == '\'') {
						// So next char after "character" is is a quote. This is good.
						parser.read();	// Now consume the quote
						return new Character(cc);
					}
					break; // If we got here, it is invalid.
					
				case 'n':
					// Possible null.
					if (parser.getInput().regionMatches(parser.nextIndex()-1, "null", 0, 4)) { //$NON-NLS-1$
						parser.skip(3);	// Skip over rest of string.
						return null;
					}
					break; // If we got here, it is invalid.
					
				case 'I':
					// Possible invalid value.
					if (parser.getInput().regionMatches(parser.nextIndex()-1, INVALID, 0, INVALID.length())) {
						parser.skip(INVALID.length()-1);	// Skip over rest of string.
						return InvalidObject.INSTANCE;
					}
					break; // If we got here, it is invalid.
					
				case '[':
					// Possible array.
					// The next field should be a number, so we'll use parseString to get the number. 
					Object size = parseString(parser);
					if (size instanceof Long) {
						parser.skipWhitespace();
						cc = parser.read();	// Se if next is ']'
						if (cc == ']') {
							// Good, well-formed first dimension
							int dim = 1;
							boolean valid = true;
							// See if there are more of just "[]". the number of them is the dim.
							while (true) {
								parser.skipWhitespace();
								cc = parser.read();
								if (cc == '[') {
									parser.skipWhitespace();
									cc = parser.read();
									if (cc == ']')
										dim++;
									else {
										// This is invalid.
										valid = false;
										parser.backup();
										break;	// No more dims.
									}
								} else {
									parser.backup();
									break;	// No more dims.
								}
							}
							if (valid) {
								parser.skipWhitespace();
								cc = parser.read();
								if (cc == '{') {
									// Good, we're at the start of the initialization code.
									int[] dims = new int[dim];
									int len = ((Long) size).intValue();
									dims[0] = len;
									Object array = Array.newInstance(Object.class, dims);
									Arrays.fill((Object[]) array, null);	// Because newInstance used above fills the array created with empty arrays when a dim>1.
									
									// Now we start filling it in.
									Object invSetting = null;	// What we will use for the invalid setting. If this is a multidim, this needs to be an array. Will not create it until needed.
									Object entry = parseString(parser);	// Get the first entry
									Class compType = array.getClass().getComponentType();
									int i = -1;
									while (true) {
										if (++i < len) {
											if (compType.isInstance(entry)) {
												// Good, it can be assigned.
												Array.set(array, i, entry);
											} else {
												// Bad. Need to set invalid.
												if (invSetting == null) {
													// We haven't created it yet.
													if (dim == 1)
														invSetting = InvalidObject.INSTANCE; // Great, one dimensional, we can use invalid directly
													else {
														// Multi-dim. Need to create a valid array that we can set.
														int[] invDims = new int[dim - 1];
														Arrays.fill(invDims, 1); // Length one all of the way so that the final component can be invalid object
														invSetting = Array.newInstance(Object.class, invDims);
														Object finalEntry = invSetting; // Final array (with component type of just Object). Start with the full array and work down.
														for (int j = invDims.length - 1; j > 0; j--) {
															finalEntry = Array.get(finalEntry, 0);
														}
														Array.set(finalEntry, 0, InvalidObject.INSTANCE);
													}
												}
												Array.set(array, i, invSetting);
											}
										}
										
										parser.skipWhitespace();
										cc = parser.read();
										if (cc == ',') {
											// Good, get next
											entry = parseString(parser);
										} else if (cc == '}') {
											// Good, reached the end.
											break;
										} else {
											if (!parser.atEnd()) {
												parser.backup();
												entry = parseString(parser); // Technically this should be invalid, but we'll let a whitespace also denote next entry.
											} else {
												// It's really screwed up. The string just ended. Log it.
												Exception e = new IllegalStateException(parser.toString());
												try {
													// See if Beaninfo plugin is available (we are running under eclipse). If so, use it, else just print to error.
													// We may be in the remote vm and so it won't be available.
													Class biPluginClass = Class.forName("org.eclipse.jem.internal.beaninfo.core.BeaninfoPlugin"); //$NON-NLS-1$
													Method getPlugin = biPluginClass.getMethod("getPlugin", (Class[]) null); //$NON-NLS-1$
													Method getLogger = biPluginClass.getMethod("getLogger", (Class[]) null); //$NON-NLS-1$
													Method log = getLogger.getReturnType().getMethod("log", new Class[] {Throwable.class, Level.class}); //$NON-NLS-1$
													Object biPlugin = getPlugin.invoke(null, (Object[]) null);
													Object logger = getLogger.invoke(biPlugin, (Object[]) null);
													log.invoke(logger, new Object[] {e, Level.WARNING});
													return InvalidObject.INSTANCE;
												} catch (SecurityException e1) {
												} catch (IllegalArgumentException e1) {
												} catch (ClassNotFoundException e1) {
												} catch (NoSuchMethodException e1) {
												} catch (IllegalAccessException e1) {
												} catch (InvocationTargetException e1) {
												} catch (NullPointerException e1) {
												}
												e.printStackTrace();	// Not in eclipse, so just print stack trace.
												return InvalidObject.INSTANCE;
											}
										}
									}
									
									return array;
								}
							}							
						}
					}
					break; // If we got here, it is invalid.
			}
		}
		return InvalidObject.INSTANCE;
	}
	
	private void writeObject(ObjectOutputStream out) throws IOException {
		// Write out any hidden stuff
		out.defaultWriteObject();
		writeObject(value, out);
	}
	
	private void writeObject(Object value, ObjectOutputStream out) throws IOException {
		if (value == null)
			out.writeObject(value);
		else {
			if (value instanceof Class)
				out.writeObject(((Class) value).getName());
			else if (!value.getClass().isArray()) {
				if (value instanceof String || value instanceof Number || value instanceof Boolean || value instanceof Character)
					out.writeObject(value);
				else
					out.writeObject(InvalidObject.INSTANCE);
			} else {
				// Array is tricky. See if it is one we can handle, if not then invalid. 
				// To indicate array, we will first write out the Class of the Component type of the array (it will
				// be converted to be Object or Object[]...).
				// This will be the clue that an array is coming. Class values will never
				// be returned, so that is how we can tell it is an array.
				// Note: The reason we are using the component type (converted to Object) is because to reconstruct on the other side we need
				// to use the component type plus length of the array's first dimension.
				// 
				// We can not just serialize the array in the normal way because it may contain invalid values, and we need to 
				// handle that. Also, if it wasn't an Object array, we need to turn it into an object array. We need consistency
				// in that it should always be an Object array.
				// So output format will be:
				// Class(component type)
				// int(size of first dimension)
				// Object(value of first entry) - Actually use out writeObject() format to allow nesting of arrays.
				// Object(value of second entry)
				// ... up to size of dimension.
				Class type = value.getClass();
				// See if final type is a valid type.
				Class ft = type.getComponentType();
				int dims = 1;
				while (ft.isArray()) {
					dims++;
					ft = ft.getComponentType();
				}
				if (ft == Object.class || ft == String.class || ft == Boolean.class || ft == Character.class || ft.isPrimitive() || ft == Class.class || Number.class.isAssignableFrom(ft)) {
					String jniType = dims == 1 ? "java.lang.Object" : MapTypes.getJNITypeName("java.lang.Object", dims-1); //$NON-NLS-1$ //$NON-NLS-2$
					try {
						Class componentType = Class.forName(jniType);
						out.writeObject(componentType);
						int length = Array.getLength(value);
						out.writeInt(length);
						for (int i = 0; i < length; i++) {
							writeObject(Array.get(value, i), out);
						}
					} catch (ClassNotFoundException e) {
						// This should never happen. Object arrays are always available.
					}
				} else
					out.writeObject(InvalidObject.INSTANCE);
			}
		}
	}
	
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		// Read in any hidden stuff
		in.defaultReadObject();
		
		value = readActualObject(in);
	}
	
	private Object readActualObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		Object val = in.readObject();
		if (val instanceof Class) {
			// It must be an array. Only Class objects that come in are Arrays of Object.
			int length = in.readInt();
			Object array = Array.newInstance((Class) val, length);
			for (int i = 0; i < length; i++) {
				Array.set(array, i, readActualObject(in));
			}
			return array;
		} else
			return val;	// It is the value itself.
	}

	
	/**
	 * Is this FeatureAttributeValue an implicit value, i.e. one that came from
	 * BeanInfo Introspection and not from an override file.
	 * 
	 * @return Returns the implicitValue.
	 * 
	 * @since 1.2.0
	 */
	public boolean isImplicitValue() {
		return implicitValue;
	}

	
	/**
	 * Set the implicit value flag.
	 * @param implicitValue The implicitValue to set.
	 * 
	 * @see #isImplicitValue()
	 * @since 1.2.0
	 */
	public void setImplicitValue(boolean implicitValue) {
		this.implicitValue = implicitValue;
	}
	
}
