// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you 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.apache.juneau.utils;

import static org.apache.juneau.testutils.TestUtils.*;
import static org.junit.Assert.*;

import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.json.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.transforms.*;
import org.junit.*;

@SuppressWarnings("rawtypes")
public class PojoQueryTest {

	//====================================================================================================
	// filterCollection, string search, 1 level
	//====================================================================================================
	@Test
	public void testFilterCollectionStringSearchOneLevel() throws Exception {
		SearchArgs sa;
		List results;

		List<A> in = new AList<A>()
			.append(new A("foo"))
			.append(new A("bar"))
			.append(new A("baz"))
		;

		PojoQuery q = new PojoQuery(in, BeanContext.DEFAULT.createSession());

		sa = SearchArgs.builder().search("f=foo").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:'foo'}]", results);

		sa = SearchArgs.builder().search("f=fo*").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:'foo'}]", results);

		sa = SearchArgs.builder().search("f=*ar").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:'bar'}]", results);

		sa = SearchArgs.builder().search("f=foo bar").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:'foo'},{f:'bar'}]", results);
	}

	public class A {
		public String f;

		A() {}

		A(String f) {
			this.f = f;
		}
	}

	//====================================================================================================
	// filterCollection, date search, 1 level
	//====================================================================================================
	@Test
	public void testFilterCollectionDateSearchOneLevel() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		WriterSerializer s = JsonSerializer.create().ssq().pojoSwaps(TemporalCalendarSwap.IsoLocalDateTime.class).build();
		B[] in;
		PojoQuery q;
		SearchArgs sa;
		List results;

		in = new B[] {
			new B(2010, 0, 1),
			new B(2011, 0, 1),
			new B(2011, 0, 31),
			new B(2012, 0, 1)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2011").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T00:00:00'},{f:'2011-01-31T00:00:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f=2011.01").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T00:00:00'},{f:'2011-01-31T00:00:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f=2011.01.01").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T00:00:00'}]", s.serialize(results));

		in = new B[] {
			new B(2011, 00, 01, 11, 59, 59),
			new B(2011, 00, 01, 12, 00, 00),
			new B(2011, 00, 01, 12, 59, 59),
			new B(2011, 00, 01, 13, 00, 00)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2011.01.01.12").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:00:00'},{f:'2011-01-01T12:59:59'}]", s.serialize(results));

		in = new B[] {
			new B(2011, 00, 01, 12, 29, 59),
			new B(2011, 00, 01, 12, 30, 00),
			new B(2011, 00, 01, 12, 30, 59),
			new B(2011, 00, 01, 12, 31, 00)
		};
		q = new PojoQuery(in, session);
		sa = SearchArgs.builder().search("f=2011.01.01.12.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:30:00'},{f:'2011-01-01T12:30:59'}]", s.serialize(results));

		in = new B[] {
			new B(2011, 00, 01, 12, 30, 29),
			new B(2011, 00, 01, 12, 30, 30),
			new B(2011, 00, 01, 12, 30, 31)
		};
		q = new PojoQuery(in, session);
		sa = SearchArgs.builder().search("f=2011.01.01.12.30.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:30:30'}]", s.serialize(results));

		// Open-ended ranges

		in = new B[] {
			new B(2000, 11, 31),
			new B(2001, 00, 01)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f>2000").build();
		results = q.filter(sa);
		assertEquals("[{f:'2001-01-01T00:00:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f>=2001").build();
		results = q.filter(sa);
		assertEquals("[{f:'2001-01-01T00:00:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f<2001").build();
		results = q.filter(sa);
		assertEquals("[{f:'2000-12-31T00:00:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f<=2000").build();
		results = q.filter(sa);
		assertEquals("[{f:'2000-12-31T00:00:00'}]", s.serialize(results));

		in = new B[] {
			new B(2011, 00, 01, 12, 29, 59),
			new B(2011, 00, 01, 12, 30, 00)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f>=2011.01.01.12.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:30:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f<2011.01.01.12.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:29:59'}]", s.serialize(results));

		in = new B[] {
			new B(2011, 00, 01, 12, 30, 59),
			new B(2011, 00, 01, 12, 31, 00)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f>2011.01.01.12.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:31:00'}]", s.serialize(results));

		sa = SearchArgs.builder().search("f<=2011.01.01.12.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2011-01-01T12:30:59'}]", s.serialize(results));

		// Closed range

		in = new B[] {
			new B(2000, 11, 31, 23, 59, 59),
			new B(2001, 00, 01, 00, 00, 00),
			new B(2003, 05, 30, 23, 59, 59),
			new B(2003, 06, 01, 00, 00, 00)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2001 - 2003.06.30").build();
		results = q.filter(sa);
		assertEquals("[{f:'2001-01-01T00:00:00'},{f:'2003-06-30T23:59:59'}]", s.serialize(results));

		// ORed timestamps

		in = new B[] {
			new B(2000, 11, 31),
			new B(2001, 00, 01),
			new B(2001, 11, 31),
			new B(2002, 00, 01)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2001 2003 2005").build();
		results = q.filter(sa);
		assertEquals("[{f:'2001-01-01T00:00:00'},{f:'2001-12-31T00:00:00'}]", s.serialize(results));

		in = new B[] {
			new B(2002, 11, 31),
			new B(2003, 00, 01),
			new B(2003, 11, 31),
			new B(2004, 00, 01)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2001 2003 2005").build();
		results = q.filter(sa);
		assertEquals("[{f:'2003-01-01T00:00:00'},{f:'2003-12-31T00:00:00'}]", s.serialize(results));

		in = new B[] {
			new B(2004, 11, 31),
			new B(2005, 00, 01),
			new B(2005, 11, 31),
			new B(2006, 00, 01)
		};
		q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=2001 2003 2005").build();
		results = q.filter(sa);
		assertEquals("[{f:'2005-01-01T00:00:00'},{f:'2005-12-31T00:00:00'}]", s.serialize(results));
	}

	public class B {
		public Calendar f;

		B() {}

		B(int year, int month, int day) {
			this.f = new GregorianCalendar(year, month, day);
		}

		B(int year, int month, int day, int hour, int minute, int second) {
			this.f = new GregorianCalendar(year, month, day, hour, minute, second);
		}
	}

	//====================================================================================================
	// filterCollection, int search, 1 level
	//====================================================================================================
	@Test
	public void testFilterCollectionIntSearchOneLevel() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		SearchArgs sa;
		List results;

		List<C> in = new AList<C>()
			.append(new C(1))
			.append(new C(2))
			.append(new C(3))
		;

		PojoQuery q = new PojoQuery(in, session);

		sa = SearchArgs.builder().search("f=1").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:1}]", results);

		sa = SearchArgs.builder().search("f>1").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:2},{f:3}]", results);

		sa = SearchArgs.builder().search("f>=2").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:2},{f:3}]", results);

		sa = SearchArgs.builder().search("f<=2").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:1},{f:2}]", results);

		sa = SearchArgs.builder().search("f<2").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:1}]", results);

		sa = SearchArgs.builder().search("f=1 3").build();
		results = q.filter(sa);
		assertObjectEquals("[{f:1},{f:3}]", results);
	}

	public class C {
		public int f;

		C() {}

		C(int f) {
			this.f = f;
		}
	}

	//====================================================================================================
	// filterCollection, view, 1 level
	//====================================================================================================
	@Test
	public void testFilterCollectionViewOneLevel() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		SearchArgs sa;
		List results;

		List<E> in = new AList<E>()
			.append(new E("foo", 1, true))
			.append(new E("bar", 2, false))
			.append(new E("baz", 3, true))
		;

		PojoQuery q = new PojoQuery(in, session);

		sa = SearchArgs.builder().view("f1").build();
		results = q.filter(sa);
		assertObjectEquals("[{f1:'foo'},{f1:'bar'},{f1:'baz'}]", results);

		sa = SearchArgs.builder().view("f2").build();
		results = q.filter(sa);
		assertObjectEquals("[{f2:1},{f2:2},{f2:3}]", results);

		sa = SearchArgs.builder().view("f3").build();
		results = q.filter(sa);
		assertObjectEquals("[{f3:true},{f3:false},{f3:true}]", results);

		sa = SearchArgs.builder().view("f3,f2,f1").build();
		results = q.filter(sa);
		assertObjectEquals("[{f3:true,f2:1,f1:'foo'},{f3:false,f2:2,f1:'bar'},{f3:true,f2:3,f1:'baz'}]", results);
	}

	public class E {
		public String f1;
		public int f2;
		public boolean f3;

		E() {}

		E(String f1, int f2, boolean f3) {
			this.f1 = f1;
			this.f2 = f2;
			this.f3 = f3;
		}
	}


	//====================================================================================================
	// testSorting
	//====================================================================================================
	@Test
	public void testSorting() throws Exception {
		BeanSession session = BeanContext.DEFAULT.createSession();
		WriterSerializer s = JsonSerializer.create().ssq().pojoSwaps(TemporalCalendarSwap.IsoLocalDateTime.class).build();
		SearchArgs sa;
		List results;

		I[] in = new I[] {
			new I(1, "foo", true, 2010, 1, 1),
			new I(2, "bar", false, 2011, 1, 1),
			new I(3, "baz", true, 2012, 1, 1),
		};

		PojoQuery q = new PojoQuery(in, session);

		sa = SearchArgs.builder().sort("f2").view("f1, f2").build();
		results = q.filter(sa);
		assertEquals("[{f1:2,f2:'bar'},{f1:3,f2:'baz'},{f1:1,f2:'foo'}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f2-").view("f1,f2").build();
		results = q.filter(sa);
		assertEquals("[{f1:1,f2:'foo'},{f1:3,f2:'baz'},{f1:2,f2:'bar'}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f3").view("f1,f3").build();
		results = q.filter(sa);
		assertEquals("[{f1:2,f3:false},{f1:1,f3:true},{f1:3,f3:true}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f3,f1+").view("f1,f3").build();
		results = q.filter(sa);
		assertEquals("[{f1:2,f3:false},{f1:1,f3:true},{f1:3,f3:true}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f3,f1-").view("f1,f3").build();
		results = q.filter(sa);
		assertEquals("[{f1:2,f3:false},{f1:3,f3:true},{f1:1,f3:true}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f1").view("f1").limit(1).position(0).build();
		results = q.filter(sa);
		assertEquals("[{f1:1}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f1").view("f1").limit(3).position(0).build();
		results = q.filter(sa);
		assertEquals("[{f1:1},{f1:2},{f1:3}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f1").view("f1").limit(1).position(2).build();
		results = q.filter(sa);
		assertEquals("[{f1:3}]", s.serialize(results));

		sa = SearchArgs.builder().sort("f1").view("f1").limit(100).position(2).build();
		results = q.filter(sa);
		assertEquals("[{f1:3}]", s.serialize(results));
	}

	public class I {
		public int f1;
		public String f2;
		public boolean f3;
		public Calendar f4;

		I() {}

		I(int f1, String f2, boolean f3, int year, int month, int day) {
			this.f1 = f1;
			this.f2 = f2;
			this.f3 = f3;
			this.f4 = new GregorianCalendar(year, month, day);
		}
	}
}