/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.jsp.core.el;

import java.io.StringReader;

import org.apache.commons.el.Expression;
import org.apache.commons.el.ExpressionString;
import org.apache.commons.el.parser.ELParser;
import org.apache.commons.el.parser.ParseException;

/**
 * Utility class to implement support functionality to "morph" JSP EL into JSF
 * EL
 * 
 * @author mengbo
 * @version 1.5
 */
public final class JSFELParserHelper {
	public static String JSF_EL_LEFT_BRACE = "#{";

	public static String JSF_EL_RIGHT_BRACE = "}";

	private JSFELParserHelper() {
		// util class, do not instantiate
	}

	/**
	 * Gets the parsed form of the given expression string. Returns either an
	 * Expression or ExpressionString.
	 */
	public static Object parseExpression(String expressionString) {
		expressionString = toJspElExpression(expressionString);

		ELParser parser = new ELParser(new StringReader(expressionString));
		try {
			Object expression = parser.ExpressionString();
			if (!(expression instanceof Expression)
					&& !(expression instanceof ExpressionString)) {
				return null;
			}

			return expression;
		} catch (ParseException e) {

			// String msg = "Invalid expression: '" + expressionString + "'";
			// log.debug(msg, e);
			// throw new ReferenceSyntaxException(msg, e);
		}
		return null;
	}

	public static boolean isValidEL(String expressionString) {
		if (expressionString == null || expressionString.length() == 0) {
			return false;
		}

		return expressionString.startsWith(JSF_EL_LEFT_BRACE)
				&& expressionString.endsWith(JSF_EL_RIGHT_BRACE);
	}

	public static String trimELBrace(String expressionString) {
		if (!isValidEL(expressionString)) {
			return expressionString;
		}
		String trimedExpression = null;

		trimedExpression = expressionString.substring(JSF_EL_LEFT_BRACE
				.length(), expressionString.length()
				- JSF_EL_RIGHT_BRACE.length());

		return trimedExpression;
	}

	/**
	 * Convert ValueBinding syntax #{ } to JSP EL syntax ${ }
	 * 
	 * @param expressionString
	 *            <code>ValueBinding</code> reference expression
	 * 
	 * @return JSP EL compatible expression
	 */
	public static String toJspElExpression(String expressionString) {
		StringBuffer sb = new StringBuffer(expressionString.length());
		int remainsPos = 0;

		for (int posOpenBrace = expressionString.indexOf('{'); posOpenBrace >= 0; posOpenBrace = expressionString
				.indexOf('{', remainsPos)) {
			if (posOpenBrace > 0) {
				if (posOpenBrace - 1 > remainsPos)
					sb.append(expressionString.substring(remainsPos,
							posOpenBrace - 1));

				if (expressionString.charAt(posOpenBrace - 1) == '$') {
					sb.append("${'${'}");
					remainsPos = posOpenBrace + 1;
					continue;
				} else if (expressionString.charAt(posOpenBrace - 1) == '#') {
					// TODO: should use \\ as escape for \ always, not just when
					// before #{
					// allow use of '\' as escape symbol for #{ (for
					// compatibility with Sun's extended implementation)
					/*
					 * if (isEscaped(expressionString, posOpenBrace - 1)) {
					 * escapes: { for (int i = sb.length() - 1; i >= 0; i--) {
					 * if (sb.charAt(i) != '\\') { sb.setLength( sb.length() -
					 * (sb.length() - i) / 2); break escapes; } }
					 * sb.setLength(sb.length() / 2); } sb.append("#{"); } else {
					 */
					sb.append("${");
					int posCloseBrace = indexOfMatchingClosingBrace(
							expressionString, posOpenBrace);
					sb.append(expressionString.substring(posOpenBrace + 1,
							posCloseBrace + 1));
					remainsPos = posCloseBrace + 1;
					continue;
					// }
				} else {
					if (posOpenBrace > remainsPos)
						sb.append(expressionString.charAt(posOpenBrace - 1));
				}
			}

			// Standalone brace
			sb.append('{');
			remainsPos = posOpenBrace + 1;
		}

		sb.append(expressionString.substring(remainsPos));

		// Create a new String to shrink mem size since we are caching
		return new String(sb.toString());
	}

	private static int findQuote(String expressionString, int start) {
		int indexofSingleQuote = expressionString.indexOf('\'', start);
		int indexofDoubleQuote = expressionString.indexOf('"', start);
		return minIndex(indexofSingleQuote, indexofDoubleQuote);
	}

	/**
	 * Return the index of the matching closing brace, skipping over quoted text
	 * 
	 * @param expressionString
	 *            string to search
	 * @param indexofOpeningBrace
	 *            the location of opening brace to match
	 * 
	 * @return the index of the matching closing brace
	 * 
	 * @throws ReferenceSyntaxException
	 *             if matching brace cannot be found
	 */
	private static int indexOfMatchingClosingBrace(String expressionString,
			int indexofOpeningBrace) {
		int len = expressionString.length();
		int i = indexofOpeningBrace + 1;

		// Loop through quoted strings
		for (;;) {
			if (i >= len) {
				throw new IllegalStateException(
						"Missing closing brace. Expression: '"
								+ expressionString + "'");
			}

			int indexofClosingBrace = expressionString.indexOf('}', i);
			i = minIndex(indexofClosingBrace, findQuote(expressionString, i));

			if (i < 0) {
				// No delimiter found
				throw new IllegalStateException(
						"Missing closing brace. Expression: '"
								+ expressionString + "'");
			}

			// 1. If quoted literal, find closing quote
			if (i != indexofClosingBrace) {
				i = indexOfMatchingClosingQuote(expressionString, i) + 1;
				if (i == 0) {
					// Note: if no match, i==0 because -1 + 1 = 0
					throw new IllegalStateException(
							"Missing closing quote. Expression: '"
									+ expressionString + "'");
				}
			} else {
				// Closing brace
				return i;
			}
		}
	}

	/**
	 * Returns the index of the matching closing quote, skipping over escaped
	 * quotes
	 * 
	 * @param expressionString
	 *            string to scan
	 * @param indexOfOpeningQuote
	 *            start from this position in the string
	 * @return -1 if no match, the index of closing quote otherwise
	 */
	private static int indexOfMatchingClosingQuote(String expressionString,
			int indexOfOpeningQuote) {
		char quote = expressionString.charAt(indexOfOpeningQuote);
		for (int i = expressionString.indexOf(quote, indexOfOpeningQuote + 1); i >= 0; i = expressionString
				.indexOf(quote, i + 1)) {
			if (!isEscaped(expressionString, i)) {
				return i;
			}
		}

		// No matching quote found
		return -1;
	}

	private static boolean isEscaped(String expressionString, int i) {
		int escapeCharCount = 0;
		while ((--i >= 0) && (expressionString.charAt(i) == '\\')) {
			escapeCharCount++;
		}

		return (escapeCharCount % 2) != 0;
	}

	/**
	 * Returns the minimum index >= 0, if any
	 * 
	 * <p>
	 * Use to find the first of two characters in a string:<br>
	 * <code>minIndex(s.indexOf('/'), indexOf('\'))</code>
	 * </p>
	 * 
	 */
	public static int minIndex(int a, int b) {
		return (a < 0) ? b : (b < 0) ? a : (a < b) ? a : b;
	}
}
