/*******************************************************************************
 * Copyright (c) 2008, 2009 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.osgi.tests.filter;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import junit.framework.*;
import org.osgi.framework.*;

public abstract class FilterTests extends TestCase {
	public static Test suite() {
		TestSuite suite = new TestSuite(FilterTests.class.getName());
		suite.addTest(BundleContextFilterTests.suite());
		suite.addTest(FrameworkUtilFilterTests.suite());
		return suite;
	}

	/**
	 * Fail with cause t.
	 * 
	 * @param message Failure message.
	 * @param t Cause of the failure.
	 */
	public static void fail(String message, Throwable t) {
		AssertionFailedError e = new AssertionFailedError(message + ": " + t.getMessage());
		e.initCause(t);
		throw e;
	}

	static final int ISTRUE = 1;
	static final int ISFALSE = 2;
	static final int ISILLEGAL = 3;

	public abstract Filter createFilter(String filterString) throws InvalidSyntaxException;

	private Dictionary getProperties() {
		Dictionary props = new Hashtable();
		props.put("room", "bedroom");
		props.put("channel", new Object[] {new Integer(34), "101"});
		props.put("status", "(on\\)*");
		List vec = new ArrayList(10);
		vec.add(new Long(150));
		vec.add("100");
		props.put("max record time", vec);
		props.put("canrecord", "true(x)");
		props.put("shortvalue", new Short((short) 1000));
		props.put("intvalue", new Integer(100000));
		props.put("longvalue", new Long(10000000000L));
		props.put("bytevalue", new Byte((byte) 10));
		props.put("floatvalue", new Float(1.01));
		props.put("doublevalue", new Double(2.01));
		props.put("charvalue", new Character('A'));
		props.put("booleanvalue", new Boolean(true));
		props.put("weirdvalue", new Hashtable());
		props.put("primintarrayvalue", new int[] {1, 2, 3});
		props.put("primlongarrayvalue", new long[] {1, 2, 3});
		props.put("primbytearrayvalue", new byte[] {(byte) 1, (byte) 2, (byte) 3});
		props.put("primshortarrayvalue", new short[] {(short) 1, (short) 2, (short) 3});
		props.put("primfloatarrayvalue", new float[] {(float) 1.1, (float) 2.2, (float) 3.3});
		props.put("primdoublearrayvalue", new double[] {1.1, 2.2, 3.3});
		props.put("primchararrayvalue", new char[] {'A', 'b', 'C', 'd'});
		props.put("primbooleanarrayvalue", new boolean[] {false});
		props.put("bigintvalue", new BigInteger("4123456"));
		props.put("bigdecvalue", new BigDecimal("4.123456"));
		props.put("*", "foo");
		props.put("!  ab", "b");
		props.put("|   ab", "b");
		props.put("&    ab", "b");
		props.put("!", "c");
		props.put("|", "c");
		props.put("&", "c");
		props.put("empty", "");
		props.put("space", new Character(' '));
		return props;
	}

	public void testFilter() {
		Dictionary props = getProperties();
		testFilter("(room=*)", props, ISTRUE);
		testFilter("(room=bedroom)", props, ISTRUE);
		testFilter("(room~= B E D R O O M )", props, ISTRUE);
		testFilter("(room=abc)", props, ISFALSE);
		testFilter(" ( room >=aaaa)", props, ISTRUE);
		testFilter("(room <=aaaa)", props, ISFALSE);
		testFilter("  ( room =b*) ", props, ISTRUE);
		testFilter("  ( room =*m) ", props, ISTRUE);
		testFilter("(room=bed*room)", props, ISTRUE);
		testFilter("  ( room =b*oo*m) ", props, ISTRUE);
		testFilter("  ( room =*b*oo*m*) ", props, ISTRUE);
		testFilter("  ( room =b*b*  *m*) ", props, ISFALSE);
		testFilter("  (& (room =bedroom) (channel ~=34))", props, ISTRUE);
		testFilter("  (&  (room =b*)  (room =*x) (channel=34))", props, ISFALSE);
		testFilter("(| (room =bed*)(channel=222)) ", props, ISTRUE);
		testFilter("(| (room =boom*)(channel=101)) ", props, ISTRUE);
		testFilter("  (! (room =ab*b*oo*m*) ) ", props, ISTRUE);
		testFilter("  (status =\\(o*\\\\\\)\\*) ", props, ISTRUE);
		testFilter("  (canRecord =true\\(x\\)) ", props, ISTRUE);
		testFilter("(max Record Time <=140) ", props, ISTRUE);
		testFilter("(shortValue >=100) ", props, ISTRUE);
		testFilter("(intValue <=100001) ", props, ISTRUE);
		testFilter("(longValue >=10000000000) ", props, ISTRUE);
		testFilter("  (  &  (  byteValue <=100)  (  byteValue >=10)  )  ", props, ISTRUE);
		testFilter("(weirdValue =100) ", props, ISFALSE);
		testFilter("(bigIntValue =4123456) ", props, ISTRUE);
		testFilter("(bigDecValue =4.123456) ", props, ISTRUE);
		testFilter("(floatValue >=1.0) ", props, ISTRUE);
		testFilter("(doubleValue <=2.011) ", props, ISTRUE);
		testFilter("(charValue ~=a) ", props, ISTRUE);
		testFilter("(booleanValue =true) ", props, ISTRUE);
		testFilter("(primIntArrayValue =1) ", props, ISTRUE);
		testFilter("(primLongArrayValue =2) ", props, ISTRUE);
		testFilter("(primByteArrayValue =3) ", props, ISTRUE);
		testFilter("(primShortArrayValue =1) ", props, ISTRUE);
		testFilter("(primFloatArrayValue =1.1) ", props, ISTRUE);
		testFilter("(primDoubleArrayValue =2.2) ", props, ISTRUE);
		testFilter("(primCharArrayValue ~=D) ", props, ISTRUE);
		testFilter("(primBooleanArrayValue =false) ", props, ISTRUE);
		testFilter("(& (| (room =d*m) (room =bed*) (room=abc)) (! (channel=999)))", props, ISTRUE);
		testFilter("(room=bedroom)", null, ISFALSE);
		testFilter("(*=foo)", props, ISTRUE);
		testFilter("(!  ab=b)", props, ISTRUE);
		testFilter("(|   ab=b)", props, ISTRUE);
		testFilter("(&=c)", props, ISTRUE);
		testFilter("(!=c)", props, ISTRUE);
		testFilter("(|=c)", props, ISTRUE);
		testFilter("(&    ab=b)", props, ISTRUE);
		testFilter("(!ab=*)", props, ISFALSE);
		testFilter("(|ab=*)", props, ISFALSE);
		testFilter("(&ab=*)", props, ISFALSE);
		testFilter("(empty=)", props, ISTRUE);
		testFilter("(empty=*)", props, ISTRUE);
		testFilter("(space= )", props, ISTRUE);
		testFilter("(space=*)", props, ISTRUE);
	}

	public void testInvalidValues() {
		Dictionary props = getProperties();
		testFilter("(intvalue=*)", props, ISTRUE);
		testFilter("(intvalue=b)", props, ISFALSE);
		testFilter("(intvalue=)", props, ISFALSE);
		testFilter("(longvalue=*)", props, ISTRUE);
		testFilter("(longvalue=b)", props, ISFALSE);
		testFilter("(longvalue=)", props, ISFALSE);
		testFilter("(shortvalue=*)", props, ISTRUE);
		testFilter("(shortvalue=b)", props, ISFALSE);
		testFilter("(shortvalue=)", props, ISFALSE);
		testFilter("(bytevalue=*)", props, ISTRUE);
		testFilter("(bytevalue=b)", props, ISFALSE);
		testFilter("(bytevalue=)", props, ISFALSE);
		testFilter("(charvalue=*)", props, ISTRUE);
		testFilter("(charvalue=)", props, ISFALSE);
		testFilter("(floatvalue=*)", props, ISTRUE);
		testFilter("(floatvalue=b)", props, ISFALSE);
		testFilter("(floatvalue=)", props, ISFALSE);
		testFilter("(doublevalue=*)", props, ISTRUE);
		testFilter("(doublevalue=b)", props, ISFALSE);
		testFilter("(doublevalue=)", props, ISFALSE);
		testFilter("(booleanvalue=*)", props, ISTRUE);
		testFilter("(booleanvalue=b)", props, ISFALSE);
		testFilter("(booleanvalue=)", props, ISFALSE);
	}

	public void testIllegal() {
		Dictionary props = getProperties();
		testFilter("", props, ISILLEGAL);
		testFilter("()", props, ISILLEGAL);
		testFilter("(=foo)", props, ISILLEGAL);
		testFilter("(", props, ISILLEGAL);
		testFilter("(abc = ))", props, ISILLEGAL);
		testFilter("(& (abc = xyz) (& (345))", props, ISILLEGAL);
		testFilter("  (room = b**oo!*m*) ) ", props, ISILLEGAL);
		testFilter("  (room = b**oo)*m*) ) ", props, ISILLEGAL);
		testFilter("  (room = *=b**oo*m*) ) ", props, ISILLEGAL);
		testFilter("  (room = =b**oo*m*) ) ", props, ISILLEGAL);
	}

	public void testScalarSubstring() {
		Dictionary props = getProperties();
		testFilter("(shortValue =100*) ", props, ISFALSE);
		testFilter("(intValue =100*) ", props, ISFALSE);
		testFilter("(longValue =100*) ", props, ISFALSE);
		testFilter("(  byteValue =1*00  )", props, ISFALSE);
		testFilter("(bigIntValue =4*23456) ", props, ISFALSE);
		testFilter("(bigDecValue =4*123456) ", props, ISFALSE);
		testFilter("(floatValue =1*0) ", props, ISFALSE);
		testFilter("(doubleValue =2*011) ", props, ISFALSE);
		testFilter("(charValue =a*) ", props, ISFALSE);
		testFilter("(booleanValue =t*ue) ", props, ISFALSE);
	}

	public void testNormalization() {
		try {
			Filter f1 = createFilter("( a = bedroom  )");
			Filter f2 = createFilter(" (a= bedroom  ) ");
			assertEquals("not equal", "(a= bedroom  )", f1.toString());
			assertEquals("not equal", "(a= bedroom  )", f2.toString());
			assertEquals("not equal", f1, f2);
			assertEquals("not equal", f2, f1);
			assertEquals("not equal", f1.hashCode(), f2.hashCode());
		} catch (InvalidSyntaxException e) {
			fail("unexpected invalid syntax", e);
		}

	}

	private void testFilter(String query, Dictionary props, int expect) {
		final ServiceReference ref = new DictionaryServiceReference(props);
		Filter f1;
		try {
			f1 = createFilter(query);

			if (expect == ISILLEGAL) {
				fail("expected exception");
			}
		} catch (InvalidSyntaxException e) {
			if (expect != ISILLEGAL) {
				fail("exception", e);
			}
			return;
		}

		boolean val = f1.match(props);
		assertEquals("wrong result", expect == ISTRUE, val);

		val = f1.match(ref);
		assertEquals("wrong result", expect == ISTRUE, val);

		String normalized = f1.toString();
		Filter f2;
		try {
			f2 = createFilter(normalized);
		} catch (InvalidSyntaxException e) {
			fail("exception", e);
			return;
		}

		val = f2.match(props);
		assertEquals("wrong result", expect == ISTRUE, val);

		val = f2.match(ref);
		assertEquals("wrong result", expect == ISTRUE, val);

		assertEquals("normalized not equal", normalized, f2.toString());

	}

	public void testComparable() {
		Filter f1 = null;
		Object comp42 = new SampleComparable("42");
		Object comp43 = new SampleComparable("43");
		Hashtable hash = new Hashtable();

		try {
			f1 = createFilter("(comparable=42)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("comparable", comp42);
		assertTrue("does not match filter", f1.match(hash));
		assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash)));

		hash.put("comparable", comp43);
		assertFalse("does match filter", f1.match(hash));
		assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));

		try {
			f1 = createFilter("(comparable<=42)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("comparable", comp42);
		assertTrue("does not match filter", f1.match(hash));
		assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash)));

		hash.put("comparable", comp43);
		assertFalse("does match filter", f1.match(hash));
		assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));

		try {
			f1 = createFilter("(comparable>=42)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("comparable", comp42);
		assertTrue("does not match filter", f1.match(hash));
		assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash)));

		hash.put("comparable", comp43);
		assertTrue("does not match filter", f1.match(hash));
		assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash)));

		try {
			f1 = createFilter("(comparable=4*2)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("comparable", comp42);
		assertFalse("does match filter", f1.match(hash));
		assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));
	}

	public void testObject() {
		Filter f1 = null;
		Object obj42 = new SampleObject("42");
		Object obj43 = new SampleObject("43");
		Hashtable hash = new Hashtable();

		try {
			f1 = createFilter("(object=42)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("object", obj42);
		assertTrue("does not match filter", f1.match(hash));
		assertTrue("does not match filter", f1.match(new DictionaryServiceReference(hash)));

		hash.put("object", obj43);
		assertFalse("does match filter", f1.match(hash));
		assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));

		try {
			f1 = createFilter("(object=4*2)");
		} catch (InvalidSyntaxException e) {
			fail("invalid syntax", e);
		}

		hash.put("object", obj42);
		assertFalse("does match filter", f1.match(hash));
		assertFalse("does match filter", f1.match(new DictionaryServiceReference(hash)));
	}

	public static class SampleComparable implements Comparable {
		private int value = -1;

		public SampleComparable(String value) {
			this.value = Integer.parseInt(value);
		}

		public int compareTo(Object o) {
			return value - ((SampleComparable) o).value;
		}

		public String toString() {
			return String.valueOf(value);
		}
	}

	public static class SampleObject {
		private int value = -1;

		public SampleObject(String value) {
			this.value = Integer.parseInt(value);
		}

		public boolean equals(Object o) {
			if (o instanceof SampleObject) {
				return value == ((SampleObject) o).value;
			}
			return false;
		}

		public String toString() {
			return String.valueOf(value);
		}
	}

	private static class DictionaryServiceReference implements ServiceReference {
		private final Dictionary dictionary;
		private final String[] keys;

		DictionaryServiceReference(Dictionary dictionary) {
			if (dictionary == null) {
				this.dictionary = null;
				this.keys = new String[] {};
				return;
			}
			this.dictionary = dictionary;
			List keyList = new ArrayList(dictionary.size());
			for (Enumeration e = dictionary.keys(); e.hasMoreElements();) {
				Object k = e.nextElement();
				if (k instanceof String) {
					String key = (String) k;
					for (Iterator i = keyList.iterator(); i.hasNext();) {
						if (key.equalsIgnoreCase((String) i.next())) {
							throw new IllegalArgumentException();
						}
					}
					keyList.add(key);
				}
			}
			this.keys = (String[]) keyList.toArray(new String[keyList.size()]);
		}

		public Object getProperty(String k) {
			for (int i = 0, length = keys.length; i < length; i++) {
				String key = keys[i];
				if (key.equalsIgnoreCase(k)) {
					return dictionary.get(key);
				}
			}
			return null;
		}

		public String[] getPropertyKeys() {
			return (String[]) keys.clone();
		}

		public int compareTo(Object reference) {
			throw new UnsupportedOperationException();
		}

		public Bundle getBundle() {
			throw new UnsupportedOperationException();
		}

		public Bundle[] getUsingBundles() {
			throw new UnsupportedOperationException();
		}

		public boolean isAssignableTo(Bundle bundle, String className) {
			throw new UnsupportedOperationException();
		}
	}
}
