package eu.dnetlib.dli.resolver.model;

import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.dnetlib.dli.DLIUtils;
import eu.dnetlib.miscutils.functional.xml.DnetXsltFunctions;
import eu.dnetlib.pid.resolver.model.ObjectProvenance;
import eu.dnetlib.pid.resolver.model.ObjectRelation;
import eu.dnetlib.pid.resolver.model.ObjectType;
import eu.dnetlib.pid.resolver.model.PID;
import org.apache.commons.lang3.StringEscapeUtils;

/**
 * The Class DLIRelation.
 */
public class DLIObjectRelation implements ObjectRelation {

	private static Gson g = new GsonBuilder().setPrettyPrinting().create();

	/**
	 * The source doi.
	 */
	private String sourceRecordId;

	/**
	 * The source doi.
	 */
	private String sourcePid;

	/**
	 * The target type.
	 */
    private ObjectType targetType = ObjectType.unknown;

	/**
	 * The target pid.
	 */
	private PID targetPID;

	/**
	 * The target title.
	 */
	private String targetTitle;

	/**
	 * The authors.
	 */
	private List<String> authors;

	/**
	 * The relation semantics.
	 */
	private String relationSemantics;


	private String inverseRelation;

	private String license;

	/**
	 * The relation provenance.
	 */
    private List<ObjectProvenance> relationProvenance;

	/**
	 * The status.
	 */
	private String completionStatus = "incomplete";

    private DLIResolvedObject extraInfo;

	/**
	 * Gets the source do
	 *
	 * @return the source doi
	 */
	public String getSourceRecordId() {
		return sourceRecordId;
	}

	@Override
	public PID getSourcePID() {
		return new PID(sourcePid, "unknown");
	}

	/**
	 * Sets the source doi.
	 *
	 * @param sourceRecordId the new source record id
	 */
	public ObjectRelation setSourceRecordId(final String sourceRecordId) {
		if (sourceRecordId != null) {
			this.sourceRecordId = sourceRecordId;
		}
		return this;
	}

	@Override
	public ObjectRelation setSourcePID(PID sourcePID) {
		this.sourcePid = sourcePID.getId();
		return this;
	}

	/**
	 * Gets the escaped xmldoi.
	 *
	 * @return the escaped xmldoi
	 */
	public String getEscapedXMLDOI() {
        return StringEscapeUtils.escapeXml11(sourceRecordId);
    }

	/**
	 * Gets the target type.
	 *
	 * @return the target type
	 */
	public ObjectType getTargetType() {
		return targetType;
	}

	/**
	 * Sets the target type.
	 *
	 * @param targetType the new target type
	 */
	public ObjectRelation setTargetType(final ObjectType targetType) {
		this.targetType = targetType;
		return this;
	}

	/**
	 * Gets the ID relation.
	 *
	 * @return the ID relation
	 */
	public String getIDRelation() {

		if ((this.getSourceRecordId() == null) || (this.getTargetPID() == null) || (this.getTargetPID().getId() == null))
			return null;
		return String.format("%s::%s", this.getSourceRecordId(), DnetXsltFunctions.md5(getTargetPID().getId().toLowerCase().trim()));
	}

	public String getIDRecord() {
		return (DnetXsltFunctions.md5(String.format("%s::%s", this.getTargetPID().getId(), this.getTargetPID().getType())));
	}

	/**
	 * Gets the target pid.
	 *
	 * @return the target pid
	 */
	public PID getTargetPID() {
		return targetPID;
	}

	/**
	 * Sets the target pid.
	 *
	 * @param targetPID the new target pid
	 */
	public ObjectRelation setTargetPID(final PID targetPID) {

		if (targetPID.getType() != null && "doi".equals(targetPID.getType().trim().toLowerCase()))
			targetPID.setId(DLIUtils.fixPID(targetPID.getId()));
		this.targetPID = targetPID;
		return this;
	}

	/**
	 * Gets the target title.
	 *
	 * @return the target title
	 */
	public String getTargetTitle() {
		if (targetTitle == null) return null;
		return StringEscapeUtils.escapeXml11(targetTitle);

	}

	/**
	 * Sets the target title.
	 *
	 * @param targetTitle the new target title
	 */
	public void setTargetTitle(final String targetTitle) {
		this.targetTitle = targetTitle;
	}

	/**
	 * Gets the relation semantics.
	 *
	 * @return the relation semantics
	 */
	public String getRelationSemantics() {
		return relationSemantics;
	}

	/**
	 * Sets the relation semantics.
	 *
	 * @param relationSemantics the new relation semantics
	 */
	public ObjectRelation setRelationSemantics(final String relationSemantics) {
		this.relationSemantics = relationSemantics;
		return this;
	}

	public String getInverseRelation() {
		return inverseRelation;
	}

	public ObjectRelation setInverseRelation(String inverseRelation) {
		this.inverseRelation = inverseRelation;
		return this;
	}

	/**
	 * Gets the relation provenance.
	 *
	 * @return the relationProvenance
	 */
    public List<ObjectProvenance> getRelationProvenance() {
        return relationProvenance;
	}

	/**
	 * Sets the relation provenance.
	 *
	 * @param relationProvenance the relationProvenance to set
	 */
    public void setRelationProvenance(final List<ObjectProvenance> relationProvenance) {
        this.relationProvenance = relationProvenance;
	}

	/**
	 * Gets the completion status.
	 *
	 * @return the completion status
	 */
	public String getCompletionStatus() {
		return this.completionStatus;
	}

	/**
	 * Sets the completion status.
	 *
	 * @param completionStatus the new completion status
	 */
	public void setCompletionStatus(final String completionStatus) {
		this.completionStatus = completionStatus;
	}

	/**
	 * Gets the source pid.
	 *
	 * @return the source pid
	 */
	public String getSourcePid() {
		return sourcePid;
	}

	/**
	 * Sets the source pid.
	 *
	 * @param sourcePid the new source pid
	 */
	public void setSourcePid(final String sourcePid) {
		this.sourcePid = sourcePid;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see Object#toString()
	 */
	@Override
	public String toString() {
		return g.toJson(this);
	}

	/**
	 * Gets the authors.
	 *
	 * @return the authors
	 */
	public List<String> getAuthors() {
		return authors;
	}

	/**
	 * Sets the authors.
	 *
	 * @param authors the new authors
	 */
	public void setAuthors(final List<String> authors) {
		this.authors = authors;
	}

	/**
	 * Gets the escaped xml authors.
	 *
	 * @return the escaped xml authors
	 */
	public List<String> getEscapedXMLAuthors() {
		if (authors != null)
            return DLIResolvedObject.escapedArray(authors);
        return null;
	}

	public String getLicenseEscapedXML() {
		if (license != null)
			return StringEscapeUtils.escapeXml11(license);
		return  null;
	}

	public String getLicense() {
		return license;
	}

	public void setLicense(String license) {
		this.license = license;
	}

	public DLIResolvedObject getExtraInfo() {
        return extraInfo;
	}

    public void setExtraInfo(final DLIResolvedObject extraInfo) {
        this.extraInfo = extraInfo;
	}
}
