package eu.dnetlib.functionality.cql.lucene;

import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import eu.dnetlib.functionality.cql.CqlGroup;
import eu.dnetlib.functionality.cql.CqlUtils;
import org.junit.Before;
import org.junit.Test;
import org.z3950.zing.cql.CQLNode;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class CqlUtilsTest {

	private Map<String, String> weights;

	@Before
	public void setUp() {
		weights = Maps.newHashMap();
		weights.put("title", "2");
		weights.put("ugo", "1.5");
		weights.put("tag", "3");
	}

	@Test
	public void test_0() {
		String query = "tag = pluto";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		assertTrue(res == null);
	}

	@Test
	public void test_filter_1() {
		String query = "creator = pippo";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		assertTrue(res.toCQL().equals(query));
	}

	@Test
	public void test_filter_2() {
		String query = "creator = pippo and tag = pluto";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		System.out.println(res.toCQL());
	}

	@Test
	public void test_filter_3() {
		String query = "creator = pippo and tag = pluto and title = pizza";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		System.out.println(res.toCQL());
	}

	@Test
	public void test_filter_4() {
		String query = "creator = pippo or tag = pluto and title = pizza";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		System.out.println(res.toCQL());
	}

	@Test
	public void test_filter_5() {
		String query = "creator = pippo and tag = pluto or title = pizza";
		CQLNode res = CqlUtils.filter(query, Lists.newArrayList("tag"));
		System.out.println(res.toCQL());
	}

	//////

	@Test
	public void test_group_0() {
		String query = "(>s=NAMESPACE s.test=800) and  creator = pippo and tag = pluto or title = pizza or title = pozzo";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("tag", "title"));
		print(query, res);
	}

	@Test
	public void test_group_01() {
		String query = "test and language exact \"fin\"";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("language", "repositorycountry"));
		print(query, res);
	}

	@Test
	public void test_group_1() {
		String query = "creator = pippo and tag = pluto or title = pizza and tag = roma";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("tag"));
		print(query, res);
	}

	@Test
	public void test_group_1_1() {
		String query = "creator = pippo and ((tag = pluto or title = pizza) and tag = roma)";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("tag"));
		print(query, res);
	}

	@Test
	public void test_group_2() {
		String query = "creator = pippo and tag = pluto or title = pizza and tag = roma";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("tag", "creator", "title"));
		print(query, res);
	}

	@Test
	public void test_group_3() {
		String query = "creator = pippo and tag = pluto or title = pizza and tag = roma";
		Map<String, CQLNode> res = CqlUtils.group(query, new ArrayList<String>());
		print(query, res);
	}

	@Test
	public void test_group_3_1() {
		String query = "creator = pippo or tag = roma";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList("tag"));
		print(query, res);
	}

	@Test
	public void test_group_3_2() {
		String query = "tag = roma or blabla or bloblo";
		Map<String, CQLNode> res = CqlUtils.group(query, Lists.newArrayList(CqlGroup.defaultTerm));
		print(query, res);
	}

	////

	@Test
	public void test_group_4_1() {
		String query = "creator = pippo and tag = pluto or title = pizza and tag = roma";
		List<String> res = CqlUtils.listTerms(query, "tag");
		System.out.println("[query: " + query + "]");
		System.out.println(res);
	}

	@Test
	public void test_group_4_2() {
		String query = "tag = pippo";
		List<String> res = CqlUtils.listTerms(query, "tag");
		System.out.println("[query: " + query + "]");
		System.out.println(res);
	}

	@Test
	public void test_group_4_3() {
		String query = "creator = pippo and tag = pluto or title = pizza or tag = roma and blabla or bloblo";
		Map<String, CQLNode> res = CqlUtils.group(query, CqlUtils.listFields(query));
		print(query, res);
	}

	@Test
	public void test_expand_1() {
		String query = "tag = roma or blabla or bloblo";
		CQLNode res = CqlUtils.expand(query, weights.keySet());
		System.out.println("[query: " + query + "]");
		System.out.println(res.toCQL());
	}

	@Test
	public void test_expand_2() {
		String query = "blabla or bloblo";
		CQLNode res = CqlUtils.expand(query, weights.keySet());
		System.out.println("[query: " + query + "]");
		System.out.println(res.toCQL());
	}

	@Test
	public void test_expand_3() {
		String query = "blabla";
		CQLNode res = CqlUtils.expand(query, weights.keySet());
		System.out.println("[query: " + query + "]");
		System.out.println(res.toCQL());
	}

	@Test
	public void test_expand_4() {
		String query = "tag = roma or blabla or bloblo";
		CQLNode res = CqlUtils.expand(query, new HashSet<String>());
		System.out.println("[query: " + query + "]");
		System.out.println(res.toCQL());
	}

	////

	@Test
	public void test_list_fields_0() {
		String query = "pippo";
		List<String> res = CqlUtils.listFields(query);
		System.out.println("[query: " + query + "]");
		System.out.println(res);
	}

	@Test
	public void test_list_fields_1() {
		String query = "tag = pippo";
		List<String> res = CqlUtils.listFields(query);
		System.out.println("[query: " + query + "]");
		System.out.println(res);
	}

	///////////////////////
	private void print(String query, Map<String, CQLNode> res) {
		System.out.println("query: [" + query + "]");
		for (Entry<String, CQLNode> e : res.entrySet()) {
			System.out.println(e.getKey() + ": [" + e.getValue().toCQL() + "]");
		}
	}

}
