package eu.dnetlib.openaire.project.domain;

import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;

/**
 * Created by claudio on 20/09/16.
 */
public class Project {

	public static final String INFO_EU_REPO_GRANT_AGREEMENT = "info:eu-repo/grantAgreement/";
	private String code;
	private String acronym;
	private String title;
	private String callIdentifier;
	private String startdate;
	private String enddate;
	private boolean oaMandateForPublications;
	private boolean oaMandateForDatasets;
	private String fundingpathid;
	private String description;
	private String funder;
	private String jurisdiction;
	private String orgLegalname;
	private String orgCountry;
	private String orgRole;
	private String firstname;
	private String secondnames;
	private String email;

	public Project() {
	}

	public String getIdnamespace() {
		String res = INFO_EU_REPO_GRANT_AGREEMENT + getFunder()+"/";
		final String fundingProgram = asFundingProgram(getFundingpathid());
		if (StringUtils.isNotBlank(fundingProgram)) {
			res += fundingProgram;
		}
		res += "/" + escapeCode(getCode());
		if (StringUtils.isNotBlank(getJurisdiction())) {
			res += "/" + getJurisdiction();
		}
		return res;
	}

	public String getListLabel() {
		return String.format("for:value:component:_%s_project_id", asFunder(getFunder()));
	}

	private String asFunder(final String legalshortname) {
		switch (legalshortname.toLowerCase()) {
		case "ec":
			return asFundingProgram(getFundingpathid()).toLowerCase();
		default:
			return legalshortname.toLowerCase();
		}
	}

	public List<String> asList() {
		return Lists.newArrayList(
				clean(getCode()),
				clean(getAcronym()),
				clean(getTitle()),
				clean(getCallIdentifier()),
				clean(getStartdate()),
				clean(getEnddate()),
				String.valueOf(isOaMandateForPublications()),
				String.valueOf(isOaMandateForDatasets()),
				clean(getDescription()),
				clean(getOrgLegalname()),
				clean(getOrgCountry()),
				clean(getOrgRole()),
				clean(getFirstname()),
				clean(getSecondnames()),
				clean(getEmail()));
	}

	private String clean(final String s) {
		return StringUtils.isNotBlank(s) ? "\"" + s.replaceAll("\\n|\\t|\\s+", " ").replace("\"","\"\"").trim() + "\"" : "";
	}

	private String escapeCode(final String code) {
		return replaceSlash(code);
	}

	private String asFundingProgram(final String fundingpathid) {
		final ArrayList<String> strings = Lists.newArrayList(Splitter.on("::").split(fundingpathid));
		if(strings.size() <= 1) throw new IllegalStateException("Unexpected funding id: "+fundingpathid);
		if(strings.size() == 2) return "";
		else return replaceSlash(strings.get(2));
	}

	private String replaceSlash(final String s) {
		return s.replaceAll("/", "%2F");
	}

	public String getCode() {
		return code;
	}

	public Project setCode(final String code) {
		this.code = code;
		return this;
	}

	public String getAcronym() {
		return acronym;
	}

	public Project setAcronym(final String acronym) {
		this.acronym = acronym;
		return this;
	}

	public String getTitle() {
		return title;
	}

	public Project setTitle(final String title) {
		this.title = title;
		return this;
	}

	public String getCallIdentifier() {
		return callIdentifier;
	}

	public Project setCallIdentifier(final String call_identifier) {
		this.callIdentifier = call_identifier;
		return this;
	}

	public String getStartdate() {
		return startdate;
	}

	public Project setStartdate(final String startdate) {
		this.startdate = startdate;
		return this;
	}

	public String getEnddate() {
		return enddate;
	}

	public Project setEnddate(final String enddate) {
		this.enddate = enddate;
		return this;
	}

	public boolean isOaMandateForPublications() {
		return oaMandateForPublications;
	}

	public Project setOaMandateForPublications(final boolean oaMandateForPublications) {
		this.oaMandateForPublications = oaMandateForPublications;
		return this;
	}

	public boolean isOaMandateForDatasets() {
		return oaMandateForDatasets;
	}

	public Project setOaMandateForDatasets(final boolean oaMandateForDatasets) {
		this.oaMandateForDatasets = oaMandateForDatasets;
		return this;
	}


	public String getFundingpathid() {
		return fundingpathid;
	}

	public Project setFundingpathid(final String fundingpathid) {
		this.fundingpathid = fundingpathid;
		return this;
	}

	public String getDescription() {
		return description;
	}

	public Project setDescription(final String description) {
		this.description = description;
		return this;
	}

	public String getJurisdiction() {
		return jurisdiction;
	}

	public Project setJurisdiction(final String jurisdiction) {
		this.jurisdiction = jurisdiction;
		return this;
	}

	public String getOrgLegalname() {
		return orgLegalname;
	}

	public Project setOrgLegalname(final String legalname) {
		this.orgLegalname = legalname;
		return this;
	}

	public String getOrgCountry() {
		return orgCountry;
	}

	public Project setOrgCountry(final String country) {
		this.orgCountry = country;
		return this;
	}

	public String getOrgRole() {
		return orgRole;
	}

	public Project setOrgRole(final String role) {
		this.orgRole = role;
		return this;
	}

	public String getFirstname() {
		return firstname;
	}

	public Project setFirstname(final String firstname) {
		this.firstname = firstname;
		return this;
	}

	public String getSecondnames() {
		return secondnames;
	}

	public Project setSecondnames(final String secondnames) {
		this.secondnames = secondnames;
		return this;
	}

	public String getEmail() {
		return email;
	}

	public Project setEmail(final String email) {
		this.email = email;
		return this;
	}

	public String getFunder() {
		return funder;
	}

	public Project setFunder(final String funder) {
		this.funder = funder;
		return this;
	}
}
