package eu.dnetlib.data.collective.harvest;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

import org.apache.commons.compress.tar.TarInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.dnetlib.enabling.resultset.IterableResultSet;
import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
import eu.dnetlib.enabling.tools.blackboard.BlackboardServerHandler;

/**
 * a BlackboardIterableResultset allows the injecton of a blackboard job and blackboardServerHandler.
 * 
 * @author claudio
 * 
 */
public class BlackboardIterableResultset extends IterableResultSet {

	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(BlackboardIterableResultset.class);

	/**
	 * metadata file name.
	 */
	private static String METADATA_FILENAME = ".metadata";

	/**
	 * the job
	 */
	private BlackboardJob job;

	/**
	 * the server handler used to set the action status for the job
	 */
	private BlackboardServerHandler blackboardServerHandler;

	/**
	 * properties read from the metadata file.
	 */
	private Properties properties;

	/**
	 * 
	 * @param iter
	 * @param fetchSize
	 * @param job
	 * @param blackboardServerHandler
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	protected BlackboardIterableResultset(final Iterable<String> iter, final int fetchSize, final BlackboardJob job,
			final BlackboardServerHandler blackboardServerHandler) {

		super(iter, fetchSize);

		this.properties = readProperties(job.getParameters().get("base_url"));
		this.job = job;
		this.blackboardServerHandler = blackboardServerHandler;
	}

	/**
	 * method reads
	 * 
	 * @param baseUrl
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private Properties readProperties(final String baseUrl) {
		log.info("READING PROPERTIES: " + baseUrl + "/" + METADATA_FILENAME);
		Properties properties = new Properties();
		try {
			properties.load(new URL(baseUrl + "/" + METADATA_FILENAME).openStream());
		} catch (IOException e) {
			log.info("couldn't read (optional) properties file, it should be: " + baseUrl + "/" + METADATA_FILENAME);
		}

//		guessTarSize(baseUrl, properties);

		return properties;
	}

	protected void guessTarSize(String baseUrl, Properties properties) {
		try {
			InputStream file = new URL(baseUrl).openStream();
			TarInputStream tar = new TarInputStream(file);
			int count = 0;
			while (tar.getNextEntry() != null)
				count++;
			
			properties.put("numberOfFiles", count);
			
			tar.close();
		} catch (IOException e) {
			log.info("Couldn't guess archive size", e);
		}

	}

	@Override
	public int getSize() {
		if (getResultSet().isOpen())
			return Math.max(getNumberOfFiles(), super.getSize());
		else
			return super.getSize();
	}

	@Override
	protected void close() {
		log.info("closing resultSet and setting blackboard job to done");
		super.close();
		blackboardServerHandler.done(job);
	}

	/////////////////// helper
	private int getNumberOfFiles() {
		try {
			return Integer.parseInt(properties.getProperty("numberOfFiles"));
		} catch (NumberFormatException e) {
			log.debug("Wrong integer format", e);
			return 0;
		}
	}

}
