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

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

import eu.dnetlib.data.index.ws.commons.event.CreateIndexEvent;
import eu.dnetlib.data.index.ws.commons.event.FeedIndexEvent;
import eu.dnetlib.data.index.ws.commons.event.IndexError;
import eu.dnetlib.data.index.ws.commons.event.client.IIndexClient;
import eu.dnetlib.data.index.ws.commons.event.response.FeedIndexResponse;
import eu.dnetlib.data.index.ws.commons.event.response.GenericEventResponse;
import eu.dnetlib.data.index.ws.commons.event.response.IndexEventResponse;
import eu.dnetlib.data.index.ws.mdformat.DriverFieldSpec;
import eu.dnetlib.data.index.ws.yadda.impl.FeedIteratorMock;
import eu.dnetlib.data.index.utils.SpringBeans;
import eu.dnetlib.data.index.utils.SpringUtils;

import pl.edu.icm.yadda.common.utils.Utils;

public class CreateTestIndex {

	private static final Log log = LogFactory.getLog(CreateTestIndex.class);
	
	public static void main(String[] args) {
		if (args.length!=2) {
			System.err.println("Usage: "+CreateTestIndex.class.getName()+" indexId docsNumber");
			return;
		}
		String indexId = args[0];
		int docsNumber = Utils.atoi(args[1]);
		if (docsNumber<0) {
			log.error("Invalid [docsNumber] parameter ("+args[1]+")");
		}
		AbstractApplicationContext context = null;
		try {
			context = (AbstractApplicationContext) SpringUtils.getSpringContext(SpringUtils.DEFAULT_RESOURCE);
			SearchModuleFacade facade = (SearchModuleFacade) context.getBean(SpringBeans.BEAN_SEARCH_MODULE_FACADE);
			CreateIndexEvent event = new CreateIndexEvent(indexId);
			event.setFormat("dmf");
			String[] fields = FeedIteratorMock.getFields();
			boolean[] fieldsTokenized = FeedIteratorMock.getFieldsTokenizedFlags();
			Collection<DriverFieldSpec> fieldSpecs = new ArrayList<DriverFieldSpec>();
			for (int i=0; i<fields.length; i++) {
				DriverFieldSpec fs = new DriverFieldSpec(fields[i]);
				fs.setTokenizable(fieldsTokenized[i]);
				fieldSpecs.add(fs);
			}
			event.setFieldSpecs(fieldSpecs);
			GenericEventResponse response = facade.notify(event);
			if (response.getStatus()!=GenericEventResponse.Status.FINISHED) {
				logError(response, "Index creation failed.");
				return;
			}
			FeedIndexEvent feedEvent = new FeedIndexEvent();
			FeedClientImpl feedClient = new FeedClientImpl();
			feedEvent.setIndexId(indexId);
			feedEvent.setIndexClient(feedClient);
			feedEvent.setFeedIterator(new FeedIteratorMock(docsNumber));
			feedEvent.setType("dmf");
			response = facade.notify(feedEvent);
			if (response.getStatus()==GenericEventResponse.Status.ERROR) {
				logError(response, "Index feed failed at start.");
				return;
			}
			FeedIndexResponse feedResponse = feedClient.getResponse();
			if (feedResponse.getStatus()!=GenericEventResponse.Status.FINISHED) {
				logError(feedResponse, "Index feed failed.");
				return;
			} else {
				log.info("Feed on ["+indexId+"] index succeeded. Number of document in the index: "+feedResponse.getIndexObjectsCount());
			}
		} catch (Exception e) {
			log.error("Error occured while creating test index");
		} finally {
			if (context!=null) {
				try {
					context.close();
				} catch (Exception e) {
					log.warn("Error occured while closing context", e);
				}
			}
		}
		
	}
	
	private static void logError(GenericEventResponse resp, String msg) {
		log.error(msg+" [status: "+resp.getStatus());
		if (resp.getErrors()!=null) {
			for (IndexError error : resp.getErrors()) {
				log.error(">> Error: ", error);
			}
		}
	}
	
}

class FeedClientImpl implements IIndexClient {

	private FeedIndexResponse response = null;
	
	public synchronized void operationFinished(IndexEventResponse response) {
		this.response = (FeedIndexResponse) response;
		notifyAll();
	}

	public synchronized FeedIndexResponse getResponse() throws InterruptedException {
		while (response==null) {
				wait();
		}
		return response;
	}
	
}