package eu.dnetlib.oai.info;

import java.util.Arrays;
import java.util.List;

import eu.dnetlib.oai.BadResumptionTokenException;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

public class ResumptionTokenImpl implements ResumptionToken {

	/**
	 * Total number of documents.
	 */
	private int nMaxElements;
	/**
	 * Requested metadata prefix.
	 */
	private String metadataPrefix;
	/**
	 * Query to use generate the requested records.
	 */
	private String query;

	/**
	 * Number of already read records.
	 */
	private int nRead;

	/**
	 * objIdentifier of the last read document.
	 */
	private String lastObjIdentifier;

	/**
	 * Requested set. Optional.
	 */
	private String requestedSet = "";

	private boolean hasDateRange = false;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String serialize() {
		String escapedQuery = StringEscapeUtils.escapeXml11(query);
		List<String> info = Arrays.asList("" + nMaxElements, metadataPrefix, escapedQuery, "" + nRead, lastObjIdentifier, "" + hasDateRange, requestedSet);
		return StringUtils.join(info, "|");

	}

	/**
	 * {@inheritDoc}
	 *
	 * @throws BadResumptionTokenException
	 */
	@Override
	public void deserialize(final String token) throws BadResumptionTokenException {
		String[] info = token.split("\\|");
		if (info.length < 6) throw new BadResumptionTokenException(token);
		this.nMaxElements = Integer.parseInt(info[0]);
		this.metadataPrefix = info[1];
		String unescapedQuery = StringEscapeUtils.unescapeXml(info[2]);
		this.query = unescapedQuery;
		this.nRead = Integer.parseInt(info[3]);
		this.lastObjIdentifier = info[4];
		this.hasDateRange = Boolean.valueOf(info[5]);
		if (info.length == 7) {
			this.requestedSet = info[6];
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getnMaxElements() {
		return nMaxElements;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setnMaxElements(final int nMaxElements) {
		this.nMaxElements = nMaxElements;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getMetadataPrefix() {
		return metadataPrefix;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setMetadataPrefix(final String metadataPrefix) {
		this.metadataPrefix = metadataPrefix;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getQuery() {
		return query;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setQuery(final String query) {
		this.query = query;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getnRead() {
		return nRead;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setnRead(final int nRead) {
		this.nRead = nRead;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getLastObjIdentifier() {
		return lastObjIdentifier;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setLastObjIdentifier(final String lastObjIdentifier) {
		this.lastObjIdentifier = lastObjIdentifier;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getRequestedSet() {
		return requestedSet;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setRequestedSet(final String requestedSet) {
		this.requestedSet = requestedSet;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean hasDateRange() {
		return this.hasDateRange;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setDateRange(final boolean hasDateRange) {
		this.hasDateRange = hasDateRange;
	}

	@Override
	public String toString() {
		return "ResumptionTokenImpl [nMaxElements=" + nMaxElements + ", metadataPrefix=" + metadataPrefix + ", query=" + query + ", nRead=" + nRead
				+ ", lastObjIdentifier=" + lastObjIdentifier + ", hasDateRange=" + hasDateRange + ", requestedSet=" + requestedSet + "]";
	}

}
