/**
 * Copyright 2008-2009 DRIVER PROJECT (ICM UW)
 * Original author: Marek Horst
 *
 * 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 eu.dnetlib.data.index;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;

import eu.dnetlib.common.utils.EprUtils;
import eu.dnetlib.data.index.ws.commons.event.CreateIndexEvent;
import eu.dnetlib.data.index.ws.commons.event.DeleteIndexEvent;
import eu.dnetlib.data.index.ws.commons.event.IIndexListener;
import eu.dnetlib.data.index.ws.mdformat.DriverFieldSpec;
import eu.dnetlib.data.index.ws.yadda.SearchModuleFacade;
import eu.dnetlib.data.index.ws.yadda.impl.SearchModuleMock;
import eu.dnetlib.data.index.utils.SpringUtils;

import pl.edu.icm.yadda.service.search.searching.SearchResult;

/**
 * Main index service facade test class.
 * @author mhorst
 *
 */
public class IndexServiceFacadeTest {

	ApplicationContext ctx;
	IIndexService indexService;
	
	
	@Before
	public void setUp() throws Exception {
		ctx = SpringUtils.getSpringContext(SpringUtils.DEFAULT_JUNIT_RESOURCE);
		indexService = (IIndexService) ctx.getBean("IndexService");
		
		SearchModuleFacade searchModuleFacade = (SearchModuleFacade) ctx.getBean("internalSearchModule");
		if (searchModuleFacade instanceof SearchModuleMock) {
			SearchModuleMock searchModuleMock = (SearchModuleMock) searchModuleFacade;
			List<SearchResult> dummySearchResults = new ArrayList<SearchResult>();
			searchModuleMock.setDummySearchResults(dummySearchResults);
		}
	}

	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void testIdentify() {
		assertNotNull(indexService);
		assertNotNull(indexService.identify());
		System.out.println(indexService.identify());
	}
	
	@Test
	public void testListIndices() {
		IIndexListener indexListener = (IIndexListener) ctx.getBean("internalSearchModule");
		assertNotNull(indexListener);
//		creating new index:
		String indexId = "someDummyIndexId";
		CreateIndexEvent createEvent = new CreateIndexEvent(indexId);
		createEvent.setFormat("DMF");
		createEvent.setLayout("index");
		List<DriverFieldSpec> fieldSpecList = new ArrayList<DriverFieldSpec>();
		fieldSpecList.add(new DriverFieldSpec("a"));
		fieldSpecList.add(new DriverFieldSpec("b"));
		fieldSpecList.add(new DriverFieldSpec("c"));
		createEvent.setFieldSpecs(fieldSpecList);
		indexListener.notify(createEvent);
		try {
//			checking list of indices
			String[] result = indexService.getListOfIndices();
			assertNotNull(result);
			assertTrue(containsString(result,indexId));
		} finally {
//			deleting index
			DeleteIndexEvent deleteEvent = new DeleteIndexEvent();
			deleteEvent.setIndexId(indexId);
			indexListener.notify(deleteEvent);
		}
	}
	
	@Test
	public void testIndexLookup() throws IndexServiceException {
		//String query = "somefield=somevalue";
		//String ixId = "all";
		//String mdFormatId = "DMF";
		//String layoutId = "index";
		//W3CEndpointReference resultSetEPR = indexService.indexLookup(ixId, query, mdFormatId, layoutId);
		//assertNotNull(resultSetEPR);
		//System.out.println("resultSetEPR: " + resultSetEPR);
		//System.out.println("resultSetID: " + EprUtils.extractResultSetId(resultSetEPR.toString()));
		
		//System.out.println("bdId: " + resultSetEPR. EprUtils.extractResultSetId(resultSetEPR));
//		TODO add more specific tests with dataprovider deployed
	}
	
	private boolean containsString(String[] table, String str) {
		if (str==null || table==null || table.length==0) {
			return false;
		} else {
			for (int i = 0; i < table.length; i++) {
				if (table[i].equals(str))
					return true;
			}
			return false;
		}
	}
	
	@Test
	public void testCSVIndexesParsing() {
		String indexStr = "i1\t, i2\n, i3";
		indexStr = indexStr.replace(" ", "").replace("\t", "").replace("\n", "");
		String[] array = StringUtils.delimitedListToStringArray(indexStr, IndexServiceFacade.INDEX_DELIMITER);
		assertNotNull(array);
		assertEquals(3, array.length);
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i]);			
		}
	}

	@Test
	public void testParsingClause() {
		String[] source = new String[4];
		source[0] = "someCql";
		source[1] = "sruclause";
		source[2] = "groupBy=xxx";
		source[3] = "groupBy=yyy";
		
		Collection<String> sruClause = new ArrayList<String>();
		Collection<String> statFields = new ArrayList<String>();
		IndexServiceFacade.parseBrowsingClauses(source, sruClause, statFields);
		assertNotNull(statFields);
		assertNotNull(sruClause);
		assertEquals(2, statFields.size());
		assertEquals(1, sruClause.size());
	}
	
	@Test
	public void testIsIterateAllParameter() {
		String param = null;
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll=true";
		assertTrue(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll=TRUE";
		assertTrue(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll = TRUE";
		assertTrue(IndexServiceFacade.isIterateAllParameter(param));
		
		param="iterateAll = false";
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll = ";
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll";
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
		param="";
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
		param="iterateAll = xxx";
		assertFalse(IndexServiceFacade.isIterateAllParameter(param));
	}
}
