/**
 * 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.ws.yadda;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.support.AbstractApplicationContext;

import eu.dnetlib.data.index.utils.SpringBeans;
import eu.dnetlib.data.index.utils.SpringUtils;

import pl.edu.icm.yadda.common.utils.Utils;
import pl.edu.icm.yadda.service.search.searching.stats.QueryStats;
import pl.edu.icm.yadda.service.search.searching.stats.QueryStatsRequest;
import pl.edu.icm.yadda.test.YTest;
import pl.edu.icm.yadda.test.YTestResult;
import pl.edu.icm.yadda.test.YTestRunner;

public class SearchBenchmark {
	private static final Log log = LogFactory.getLog(SearchBenchmark.class);
	
	public static void main(String[] args) {
		if (args.length==0) {
			System.err.println("Usage: "+SearchBenchmark.class.getName()+" indexId querySize");
			return;
		}
		String indexId = args[0];
		int querySize = 100;
		if (args.length>1) {
			querySize = Utils.atoi(args[1]);
			if (querySize<=0) {
				System.err.println("Invalid [querySize] parameters");
				return;
			}
		}
		AbstractApplicationContext context = (AbstractApplicationContext) SpringUtils.getSpringContext(SpringUtils.DEFAULT_RESOURCE);
		SearchModuleFacade facade = (SearchModuleFacade) context.getBean(SpringBeans.BEAN_SEARCH_MODULE_FACADE);
		YTestRunner testRunner = new YTestRunner();
		YTestResult result = testRunner.runTest(new StatsTest(indexId, querySize, facade), 5, 100);
		log.info("Stats test runs: "+result.getTestRuns());
		log.info("Stats average time: "+result.getAvgTime()+" ms");
		result = testRunner.runTest(new SearchTest(indexId, querySize, facade), 5, 100);
		log.info("Search test runs: "+result.getTestRuns());
		log.info("Search average time: "+result.getAvgTime()+" ms");
		context.close();
	}
	
}

abstract class AbstractTest implements YTest {
	protected SearchModuleFacade searchModuleFacade;
	protected String indexId;
	protected int counter;
	protected int querySize;
	protected DriverQuery query;
	protected String[] queries = new String[] {
			"dc:creator any \"unixxs itcorp\""
	};
	
	public AbstractTest(String indexId, int querySize, SearchModuleFacade searchModuleFacade) {
		this.searchModuleFacade = searchModuleFacade;
		this.indexId = indexId;
		this.querySize = querySize;
	}
	
	public void preTest() throws Exception {
		query = new DriverQuery();
		query.setCqlQuery(queries[counter++ % queries.length]);
		query.setSize(querySize);
	}
	
	public void postTest() {
		// do nothing
	}
}

class SearchTest extends AbstractTest {
	public SearchTest(String indexId, int querySize, SearchModuleFacade searchModuleFacade) {
		super(indexId, querySize, searchModuleFacade);
	}	

	public void runTest() throws Exception {
		searchModuleFacade.search(query, new String[] {indexId});
	}	
}


class StatsTest extends AbstractTest {

	private QueryStatsRequest statsRequest;
		
	public StatsTest(String indexId, int querySize, SearchModuleFacade searchModuleFacade) {
		super(indexId, querySize, searchModuleFacade);
		List<String> statFields = new ArrayList<String>();
		statFields.add("dr:repositoryname");
		statFields.add("dr:repositorycountry");
		statFields.add("dc:language");
		statsRequest = new QueryStatsRequest(statFields);
	}

	public void runTest() throws Exception {
		QueryStats res = searchModuleFacade.getQueryStats(statsRequest, query, new String[] {indexId});
		if (counter<3) {
			System.err.println("found: "+res.getResultsNumber());
		}
	}
	
}