package eu.dnetlib.data.utils;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.dnetlib.data.mdstore.plugins.objects.Project;

/**
 * Created by sandro on 12/6/16.
 */
public class XsltFunctions {

	private static final Log log = LogFactory.getLog(XsltFunctions.class);

	public static String cleanNames(final String s) {
		if (StringUtils.isBlank(s)) { return ""; }
		return cleanNames(s, StringUtils.countMatches(s, ",") > 1 ? "," : ";");
	}

	public static String extractYear(final String s) {
		if (StringUtils.isBlank(s)) { return ""; }
		final Matcher m = Pattern.compile("^.*(\\d{4}).*$").matcher(s);
		return m.matches() ? m.group(1) : "";
	}

	private static String cleanNames(final String s, final String sep) {
		return Arrays.stream(s.split(sep))
				.map(String::trim)
				.map(XsltFunctions::clean)
				.map(XsltFunctions::capitalize)
				.filter(StringUtils::isNotBlank)
				.collect(Collectors.joining("#"));
	}

	private static String clean(final String s) {
		return s.replaceAll("\\(.*\\)", "")
				.replaceAll("\\[.*\\]", "")
				.replaceAll("(?i)^et\\.? al(\\.|\\s)*$", "")
				.replaceAll("(?i)\\s*et\\.? al(\\.|\\s)*$", "")
				.replaceAll("\\d|\\*", "")
				.replaceAll("^(\\s|\\-|\\.)+", "")
				.replaceAll("\\,", "")
				.replaceAll("\\.", ". ")
				.trim();
	}

	public static String cleanDoi(final String doi) {
		if (StringUtils.isBlank(doi)) { return ""; }

		final String x = doi.replaceAll("\\?", "")
				.replaceAll("\\s*\\/\\s*", "/")
				.replaceAll("\\s*\\-\\s*", "-")
				.trim()
				.replaceAll("\\s", "_")
				.toLowerCase();

		if (!x.equals(doi)) {
			log.info("Cleaning doi: " + doi + " -> " + x);
		}

		return x;
	}

	public static String capitalize(final String s) {
		return Arrays.stream(fixApostrophes(s.toLowerCase()).split(" "))
				.map(p -> Arrays.stream(p.split("-"))
						.map(StringUtils::capitalize)
						.collect(Collectors.joining("-")))
				.map(StringUtils::capitalize)
				.collect(Collectors.joining(" "));
	}

	public static String fixApostrophes(final String s) {
		return s.replaceAll("'a", "'A").replaceAll("'e", "'E").replaceAll("'i", "'I").replaceAll("'o", "'O").replaceAll("'u", "'U")
				.replaceAll("a'", "à").replaceAll("e'", "è").replaceAll("i'", "ì").replaceAll("o'", "ò").replaceAll("u'", "ù");
	}

	public static boolean isValidProject(final String id) {
		return Project.isValid(id);
	}

	public static String projectLongId(final String funder,
			final String program,
			final String code,
			final String jurisdiction,
			final String name,
			final String acronym) {

		return String.format("info:eu-repo/grantAgreement/%s/%s/%s/%s/%s/%s",
				funder.replaceAll("/", "%2F"),
				program.replaceAll("/", "%2F"),
				code.replaceAll("/", "%2F"),
				jurisdiction.replaceAll("/", "%2F"),
				name.replaceAll("/", "%2F"),
				acronym.replaceAll("/", "%2F"));

	}

	public static String calculatePersonName(final String s) {
		final Pattern pattern = Pattern.compile("info:cnr-pdr\\/author\\/(.+):(.+)\\/(.+)\\/(.+)");
		final Matcher matcher = pattern.matcher(s);
		return matcher.find() ? capitalize(String.format("%s, %s", matcher.group(3), matcher.group(4))) : "";
	}

	public static String serverName(final String s) {
		try {
			return new URL(s).getHost();
		} catch (final MalformedURLException e) {
			return "Unknown";
		}
	}

	public static String md5(final String s) {
		return DigestUtils.md5Hex(s);
	}

	// <xsl:for-each select="tokenize(istiFunction:cleanName(.), ';')">
	// <xsl:choose>
	// <xsl:when test="matches(normalize-space(.), ',(\s*[a-zA-Z]\.)+$')">
	// <creator>
	// <creatorName>
	// <xsl:value-of select="normalize-space(translate(.,',',' '))"/>
	// </creatorName>
	// </creator>
	// </xsl:when>
	//
	// <xsl:when test="matches(normalize-space(.), '(^[a-zA-Z\.]+,\s?[a-zA-Z\.\s]+$)|(^[a-zA-Z\.\s]+,\s?[a-zA-Z\.]+$)')">
	// <creator>
	// <creatorName>
	// <xsl:value-of select="normalize-space(translate(.,',',' '))"/>
	// </creatorName>
	// </creator>
	// </xsl:when>
	//
	// <xsl:otherwise>
	// <xsl:for-each select="tokenize(., ',')">
	// <creator>
	// <creatorName>
	// <xsl:value-of select="normalize-space(.)"/>
	// </creatorName>
	// </creator>
	// </xsl:for-each>
	// </xsl:otherwise>
	// </xsl:choose>
	// </xsl:for-each>
	//

}
