package eu.dnetlib.openaire.api;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import eu.dnetlib.miscutils.functional.hash.Hashing;
import eu.dnetlib.rmi.enabling.ISLookUpService;
import org.apache.commons.lang3.StringUtils;

/**
 * Created by michele on 15/01/16.
 */
public class SinglePublicationSubmitterUtils {

	private final ISLookUpService lookupService;

	public SinglePublicationSubmitterUtils(final ISLookUpService lookupService) {
		this.lookupService = lookupService;
	}

	public Map<String, String> calculateProjectInfo(final String link) {
		final Map<String, String> info = new HashMap<String, String>();
		final String[] arr = link.split("/");
		//info:eu-repo/grantAgreement/EC/FP7/244909/EU/Making Capabilities Work/WorkAble

		final String funderId = calculateFunderId(arr[2]);
		info.put("id", calculateProjectId(arr[2], arr[3], arr[4]));
		info.put("funderShortName", arr[2]);
		info.put("fundingName", arr[3]);
		info.put("code", arr[4]);
		info.put("jurisdiction", arr[5]);
		info.put("title", StringUtils.isNotBlank(arr[6]) ? arr[6] : arr[7]);
		info.put("acronym", arr[7]);
		info.put("funderId", funderId);
		info.put("funderName", calculateFunderName(arr[2]));
		info.put("fundingId", funderId + "::" + arr[3]);

		return info;
	}

	private String calculateProjectId(final String funderShortName, String funding, String code) {
		final String suffix = Hashing.md5(code);

		if (funderShortName.equalsIgnoreCase("ec")) {
			if (funding.equalsIgnoreCase("fp7")) {
				return "corda_______::" + suffix;
			} else {
				return "corda__h2020::" + suffix;
			}
		} else if (funderShortName.equalsIgnoreCase("arc")) {
			return "arc_________::" + suffix;
		} else if (funderShortName.equalsIgnoreCase("fct")) {
			return "fct_________::" + suffix;
		} else if (funderShortName.equalsIgnoreCase("nhmrc")) {
			return "nhmrc_______::" + suffix;
		} else if (funderShortName.equalsIgnoreCase("wt")) {
			return "wt__________::" + suffix;
		} else {
			return "";
		}
	}

	private String calculateFunderId(final String funderShortName) {
		if (funderShortName.equalsIgnoreCase("ec")) {
			return "ec__________::EC";
		} else if (funderShortName.equalsIgnoreCase("arc")) {
			return "arc_________::ARC";
		} else if (funderShortName.equalsIgnoreCase("fct")) {
			return "fct_________::FCT";
		} else if (funderShortName.equalsIgnoreCase("nhmrc")) {
			return "nhmrc_______::NHMRC";
		} else if (funderShortName.equalsIgnoreCase("wt")) {
			return "wt__________::WT";
		} else {
			return "";
		}
	}

	private String calculateFunderName(final String funderShortName) {
		if (funderShortName.equalsIgnoreCase("ec")) {
			return "European Commission";
		} else if (funderShortName.equalsIgnoreCase("arc")) {
			return "Australian Research Council (ARC)";
		} else if (funderShortName.equalsIgnoreCase("fct")) {
			return "FundaÃ§Ã£o para a CiÃªncia e a Tecnologia";
		} else if (funderShortName.equalsIgnoreCase("nhmrc")) {
			return "National Health and Medical Research Council (NHMRC)";
		} else if (funderShortName.equalsIgnoreCase("wt")) {
			return "Wellcome Trust";
		} else {
			return "";
		}
	}

	public List<ContextInfo> processContexts(List<String> list) {
		return Lists.newArrayList(Lists.transform(list, new Function<String, ContextInfo>() {
			@Override
			public ContextInfo apply(final String s) {
				return createContextInfo(s.split("::"), 0);
			}

			private ContextInfo createContextInfo(final String[] arr, final int pos) {
				final StringWriter id = new StringWriter();
				id.write(arr[0]);
				for (int i = 0; i < pos; i++) {
					id.write("::");
					id.write(arr[i + 1]);
				}
				final String elem = (pos == 0) ? "context" : (pos == 1) ? "category" : "concept";
				final ContextInfo info = new ContextInfo(elem, id.toString());
				if (pos + 1 < arr.length) {
					info.getChildren().add(createContextInfo(arr, pos + 1));
				}
				return info;
			}
		}));

	}

	public class ContextInfo {

		private String elem;
		private String id;
		private List<ContextInfo> children = new ArrayList<ContextInfo>();

		public ContextInfo(final String elem,
				final String id) {
			this.elem = elem;
			this.id = id;
		}

		public String getElem() {
			return elem;
		}

		public void setElem(final String elem) {
			this.elem = elem;
		}

		public String getId() {
			return id;
		}

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

		public List<ContextInfo> getChildren() {
			return children;
		}

		public void setChildren(final List<ContextInfo> children) {
			this.children = children;
		}

		public boolean isRoot() {
			return elem.equals("context");
		}
	}
}
