package eu.dnetlib.actionmanager.set;

import java.io.Serializable;
import java.text.ParseException;
import java.util.*;

import javax.xml.bind.annotation.XmlRootElement;

import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import org.apache.commons.lang.time.DateUtils;

@XmlRootElement
public class ActionManagerSet implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7262893241919858735L;
	public static final String[] DATE_PATTERNS = new String[]{"yyyy-MM-dd\'T\'hh:mm:ss+00:00", "yyyy-MM-dd\'T\'hh:mm:ssXXX"};

	public enum ImpactTypes {
		ONLY_INSERT, INSERT_UPDATE
	}

	private String id;
	private String name;
	private ImpactTypes impact = ImpactTypes.INSERT_UPDATE;
	private String directory;
	private String pathToLatest;
	private RawSet latest;
	private TreeSet<RawSet> expired;

	public ActionManagerSet() {
		this.expired = new TreeSet<RawSet>(getRawSetComparator());
	}

	public ActionManagerSet(final String id, final String name, final String directory) {
		this(id, name, directory, ImpactTypes.INSERT_UPDATE, null);
	}

	public ActionManagerSet(final String id, final String name, final String directory, final ImpactTypes impact, final RawSet latest) {
		this(id, name, directory, impact, null, latest);
	}

	public ActionManagerSet(final String id, final String name, final String directory, final ImpactTypes impact, final String pathToLatest, final RawSet latest) {
		super();
		this.id = id;
		this.name = name;
		this.directory = directory;
		this.impact = impact;
		this.pathToLatest = pathToLatest;
		this.latest = latest;
		this.expired = new TreeSet<RawSet>(getRawSetComparator());
	}

	public String getId() {
		return id;
	}

	public void setId(final String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(final String name) {
		this.name = name;
	}

	public ImpactTypes getImpact() {
		return impact;
	}

	public void setImpact(final ImpactTypes impact) {
		this.impact = impact;
	}

	public String getPathToLatest() {
		return pathToLatest;
	}

	public void setPathToLatest(final String pathToLatest) {
		this.pathToLatest = pathToLatest;
	}

	@Override
	public String toString() {
		return "[ id: " + id + ", name: " + name + ", impact: " + impact + " ]";
	}

	public RawSet getLatest() {
		return latest;
	}

	public void setLatest(final RawSet latest) {
		this.latest = latest;
	}

	public void setLatest(final String rawSetId, final String creationDate, final String lastUpdate) {
		setLatest(new RawSet(rawSetId.trim(), creationDate.trim(), lastUpdate.trim()));
	}

	private Comparator<RawSet> getRawSetComparator() {
		return new Comparator<RawSet>() {
			@Override
			public int compare(final RawSet o1, final RawSet o2) {
				try {
					final Date d1 = DateUtils.parseDate(o1.getLastUpdate(), DATE_PATTERNS);
					final Date d2 = DateUtils.parseDate(o2.getLastUpdate(), DATE_PATTERNS);
					return d1.compareTo(d2);
				} catch (ParseException e) {
					throw new RuntimeException(
							String.format("unable to parse dates: %s, %s. Known patterns: %s", o1.getLastUpdate(), o2.getLastUpdate(), Arrays.asList(DATE_PATTERNS)));
				}
			}
		};
	}

	public Set<RawSet> getExpired() {
		return expired;
	}

	public void addExpired(final String rawSetId, final String creationDate, final String lastUpdate) {
		addExpired(new RawSet(rawSetId.trim(), creationDate.trim(), lastUpdate.trim()));
	}

	public void addExpired(final RawSet rawSet) {
		getExpired().add(rawSet);
	}

	public String getDirectory() {
		return directory;
	}

	public void setDirectory(final String directory) {
		this.directory = directory;
	}
}
