package eu.dnetlib.download.plugin;

import java.io.File;
import java.io.FileFilter;
import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The Class PathRetreiver.
 */
public class PathRetreiver {

	private static final Log log = LogFactory.getLog(PathRetreiver.class);

	/** The instance. */
	private static PathRetreiver instance;

	/**
	 * Gets the single instance of PathRetreiver.
	 *
	 * @param base_path
	 *            the base_path
	 * @return single instance of PathRetreiver
	 */
	public static PathRetreiver getInstance(final String base_path) {
		if (instance == null) {
			instance = new PathRetreiver();
			instance.setBase_path(base_path);
		}
		return instance;
	}

	/** The base_path. */
	private String base_path;

	/** The values. */
	private TreeMap<Integer, InfoPath> values;

	/**
	 * Bootstrap.
	 */
	private void bootstrap() {
		values = new TreeMap<>();
		File basePath = new File(this.base_path);
		File[] selectedFiles = basePath.listFiles(pathname -> pathname.isDirectory());

		for (File f : selectedFiles) {
			String lower = StringUtils.substringAfter(StringUtils.substringBefore(f.getName(), "_"), "PMC");
			String upper = StringUtils.substringAfter(StringUtils.substringAfter(f.getName(), "_"), "PMC");
			String path = f.getPath();
			InfoPath i = new InfoPath();
			i.setLower(Integer.parseInt(lower));
			i.setUpper(Integer.parseInt(upper));
			i.setPath(path);
			values.put(i.getLower(), i);
		}


		if (log.isDebugEnabled()) {
			for (InfoPath p : values.values()) {
				log.debug(String.format("%s -- %s : %s", p.getLower(), p.getUpper(), p.getPath()));
			}
		}
	}

	/**
	 * Gets the path for pmcid.
	 *
	 * @param pmcID
	 *            the pmc id
	 * @return the path for pmcid
	 */
	public String getPathForPMCID(final int pmcID) {
		if (values == null) {
			bootstrap();
		}

		Map.Entry<Integer, InfoPath> infoPath = values.floorEntry(pmcID);
		if (infoPath != null) {

			final String currentPath = infoPath.getValue().getPath() + "/" + pmcID + ".xml";
			final File f = new File(currentPath);
			log.debug(String.format("try to search in path %s", currentPath));
			String s = null;
			if (f.exists()) {
				s = f.getPath();
				log.debug(String.format("found in %s", s));
			} else {
				log.debug(String.format("not found in %s", s));
			}
			return s;
		}
		log.debug(String.format("PMC with ID: %s not found", pmcID));
		return null;
	}

	/**
	 * Sets the base_path.
	 *
	 * @param base_path
	 *            the new base_path
	 */
	public void setBase_path(final String base_path) {
		this.base_path = base_path;
	}

	/**
	 * Gets the base_path.
	 *
	 * @return the base_path
	 */
	public String getBase_path() {
		return this.base_path;
	}
}
