/*
 * $Id: FilterImpl.java 44 2007-07-13 20:49:41Z hargrave@us.ibm.com $
 * 
 * Copyright (c) 2000 Gatespace AB. All Rights Reserved.
 * Copyright (c) OSGi Alliance (2002, 2006, 2007). All Rights Reserved.
 *
 * 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 org.osgi.impl.bundle.obr.resource;

import java.lang.reflect.*;
import java.math.BigInteger;
import java.util.*;

public class FilterImpl {
	final char		WILDCARD	= 65535;

	final int		EQ			= 0;
	final int		LE			= 1;
	final int		GE			= 2;
	final int		APPROX		= 3;
	final int		LESS		= 4;
	final int		GREATER		= 5;
	final int		SUBSET		= 6;
	final int		SUPERSET	= 7;

	private String	filter;

	abstract class Query {
		static final String	GARBAGE		= "Trailing garbage";
		static final String	MALFORMED	= "Malformed query";
		static final String	EMPTY		= "Empty list";
		static final String	SUBEXPR		= "No subexpression";
		static final String	OPERATOR	= "Undefined operator";
		static final String	TRUNCATED	= "Truncated expression";
		static final String	EQUALITY	= "Only equality supported";

		private String		tail;

		boolean match() throws IllegalArgumentException {
			tail = filter;
			boolean val = doQuery();
			if (tail.length() > 0)
				error(GARBAGE);
			return val;
		}

		private boolean doQuery() throws IllegalArgumentException {
			if (tail.length() < 3 || !prefix("("))
				error(MALFORMED);
			boolean val;

			switch (tail.charAt(0)) {
				case '&' :
					val = doAnd();
					break;
				case '|' :
					val = doOr();
					break;
				case '!' :
					val = doNot();
					break;
				default :
					val = doSimple();
					break;
			}

			if (!prefix(")"))
				error(MALFORMED);
			return val;
		}

		private boolean doAnd() throws IllegalArgumentException {
			tail = tail.substring(1);
			boolean val = true;
			if (!tail.startsWith("("))
				error(EMPTY);
			do {
				if (!doQuery())
					val = false;
			} while (tail.startsWith("("));
			return val;
		}

		private boolean doOr() throws IllegalArgumentException {
			tail = tail.substring(1);
			boolean val = false;
			if (!tail.startsWith("("))
				error(EMPTY);
			do {
				if (doQuery())
					val = true;
			} while (tail.startsWith("("));
			return val;
		}

		private boolean doNot() throws IllegalArgumentException {
			tail = tail.substring(1);
			if (!tail.startsWith("("))
				error(SUBEXPR);
			return !doQuery();
		}

		private boolean doSimple() throws IllegalArgumentException {
			int op = 0;
			Object attr = getAttr();

			if (prefix("="))
				op = EQ;
			else if (prefix("<="))
				op = LE;
			else if (prefix(">="))
				op = GE;
			else if (prefix("~="))
				op = APPROX;
			else if (prefix("*>"))
				op = SUPERSET;
			else if (prefix("<*"))
				op = SUBSET;
			else if (prefix("<"))
				op = LESS;
			else if (prefix(">"))
				op = GREATER;
			else
				error(OPERATOR);

			return compare(attr, op, getValue());
		}

		private boolean prefix(String pre) {
			if (!tail.startsWith(pre))
				return false;
			tail = tail.substring(pre.length());
			return true;
		}

		private Object getAttr() {
			int len = tail.length();
			int ix = 0;
			label: for (; ix < len; ix++) {
				switch (tail.charAt(ix)) {
					case '(' :
					case ')' :
					case '<' :
					case '>' :
					case '=' :
					case '~' :
					case '*' :
					case '}' :
					case '{' :
					case '\\' :
						break label;
				}
			}
			String attr = tail.substring(0, ix).toLowerCase();
			tail = tail.substring(ix);
			return getProp(attr);
		}

		abstract Object getProp(String key);

		private String getValue() {
			StringBuffer sb = new StringBuffer();
			int len = tail.length();
			int ix = 0;
			label: for (; ix < len; ix++) {
				char c = tail.charAt(ix);
				switch (c) {
					case '(' :
					case ')' :
						break label;
					case '*' :
						sb.append(WILDCARD);
						break;
					case '\\' :
						if (ix == len - 1)
							break label;
						sb.append(tail.charAt(++ix));
						break;
					default :
						sb.append(c);
						break;
				}
			}
			tail = tail.substring(ix);
			return sb.toString();
		}

		private void error(String m) throws IllegalArgumentException {
			throw new IllegalArgumentException(m + " " + tail);
		}

		private boolean compare(Object obj, int op, String s) {
			if (obj == null) {
				// No value is ok for a subset
				if (op == SUBSET)
					return true;

				// No value is ok for a superset when the value is
				// empty
				if (op == SUPERSET) {
					return s.trim().length() == 0;
				}

				return false;
			}
			try {
				Class numClass = obj.getClass();
				if (numClass == String.class) {
					return compareString((String) obj, op, s);
				}
				else if (numClass == Character.class) {
					return compareString(obj.toString(), op, s);
				}
				else if (numClass == Long.class) {
					return compareSign(op, Long.valueOf(s)
							.compareTo((Long) obj));
				}
				else if (numClass == Integer.class) {
					return compareSign(op, Integer.valueOf(s).compareTo(
							(Integer) obj));
				}
				else if (numClass == Short.class) {
					return compareSign(op, Short.valueOf(s).compareTo(
							(Short) obj));
				}
				else if (numClass == Byte.class) {
					return compareSign(op, Byte.valueOf(s)
							.compareTo((Byte) obj));
				}
				else if (numClass == Double.class) {
					return compareSign(op, Double.valueOf(s).compareTo(
							(Double) obj));
				}
				else if (numClass == Float.class) {
					return compareSign(op, Float.valueOf(s).compareTo(
							(Float) obj));
				}
				else if (numClass == Boolean.class) {
					if (op != EQ)
						return false;
					int a = Boolean.valueOf(s).booleanValue() ? 1 : 0;
					int b = ((Boolean) obj).booleanValue() ? 1 : 0;
					return compareSign(op, a - b);
				}
				else if (numClass == BigInteger.class) {
					return compareSign(op, new BigInteger(s)
							.compareTo((BigInteger) obj));
				}
				else if (obj instanceof Collection) {
					if (op == SUBSET || op == SUPERSET) {
						StringSet set = new StringSet(s);
						if (op == SUBSET)
							return set.containsAll((Collection) obj);
						else
							return ((Collection) obj).containsAll(set);
					}

					for (Iterator i = ((Collection) obj).iterator(); i
							.hasNext();) {
						Object element = i.next();
						if (compare(element, op, s))
							return true;
					}
				}
				else if (numClass.isArray()) {
					int len = Array.getLength(obj);
					for (int i = 0; i < len; i++)
						if (compare(Array.get(obj, i), op, s))
							return true;
				}
				else {
					try {
						if (op == SUPERSET || op == SUBSET) {
							StringSet set = new StringSet(s);
							if (op == SUPERSET)
								return set.contains(obj);
							else
								return set.size() == 0
										|| (set.size() == 1 && set.iterator()
												.next().equals(obj));
						}
						else {
							Constructor constructor = numClass
									.getConstructor(new Class[] {String.class});
							Object instance = constructor
									.newInstance(new Object[] {s});
							switch (op) {
								case EQ :
									return obj.equals(instance);
								case LESS :
									return ((Comparable) obj)
											.compareTo(instance) < 0;
								case GREATER :
									return ((Comparable) obj)
											.compareTo(instance) > 0;
								case LE :
									return ((Comparable) obj)
											.compareTo(instance) <= 0;
								case GE :
									return ((Comparable) obj)
											.compareTo(instance) >= 0;
							}
						}
					}
					catch (Exception e) {
						e.printStackTrace();
						// Ignore
					}
				}
			}
			catch (Exception e) {
			}
			return false;
		}
	}

	class DictQuery extends Query {
		private Map	dict;

		DictQuery(Map dict) {
			this.dict = dict;
		}

		Object getProp(String key) {
			return dict.get(key);
		}
	}

	public FilterImpl(String filter) throws IllegalArgumentException {
		// NYI: Normalize the filter string?
		this.filter = filter;
		if (filter == null || filter.length() == 0)
			throw new IllegalArgumentException("Null query");
	}

	public boolean match(Map dict) {
		try {
			return new DictQuery(dict).match();
		}
		catch (IllegalArgumentException e) {
			return false;
		}
	}

	public String toString() {
		return filter;
	}

	public boolean equals(Object obj) {
		return obj != null && obj instanceof FilterImpl
				&& filter.equals(((FilterImpl) obj).filter);
	}

	public int hashCode() {
		return filter.hashCode();
	}

	boolean compareString(String s1, int op, String s2) {
		switch (op) {
			case EQ :
				return patSubstr(s1, s2);
			case APPROX :
				return patSubstr(fixupString(s1), fixupString(s2));
			default :
				return compareSign(op, s2.compareTo(s1));
		}
	}

	boolean compareSign(int op, int cmp) {
		switch (op) {
			case LE :
				return cmp >= 0;
			case GE :
				return cmp <= 0;
			case EQ :
				return cmp == 0;
			default : /* APPROX */
				return cmp == 0;
		}
	}

	String fixupString(String s) {
		StringBuffer sb = new StringBuffer();
		int len = s.length();
		boolean isStart = true;
		boolean isWhite = false;
		for (int i = 0; i < len; i++) {
			char c = s.charAt(i);
			if (Character.isWhitespace(c)) {
				isWhite = true;
			}
			else {
				if (!isStart && isWhite)
					sb.append(' ');
				if (Character.isUpperCase(c))
					c = Character.toLowerCase(c);
				sb.append(c);
				isStart = false;
				isWhite = false;
			}
		}
		return sb.toString();
	}

	boolean patSubstr(String s, String pat) {
		if (s == null)
			return false;
		if (pat.length() == 0)
			return s.length() == 0;
		if (pat.charAt(0) == WILDCARD) {
			pat = pat.substring(1);
			for (;;) {
				if (patSubstr(s, pat))
					return true;
				if (s.length() == 0)
					return false;
				s = s.substring(1);
			}
		}
		else {
			if (s.length() == 0 || s.charAt(0) != pat.charAt(0))
				return false;
			return patSubstr(s.substring(1), pat.substring(1));
		}
	}
}
