package eu.dnetlib.pid.service;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Node;
import org.socialhistoryservices.pid.LocAttType;
import org.socialhistoryservices.pid.LocationType;
import org.socialhistoryservices.pid.PidType;

import com.google.common.collect.Lists;

public class PIDAssignerHelper {

	private static final Log log = LogFactory.getLog(PIDAssignerHelper.class); // NOPMD by marko on 11/24/08 5:02 PM

	private String unavailableURL;

	public List<LocationType> getLocationTypeList(PIDAssignmentRule r, Node baseNode) {
		if (!r.hasLocattRules()) {
			log.fatal("Rule " + r + "with no locattRules. This is unexpected in getLocationTypeList!");
			return null;
		}
		List<LocationType> locations = Lists.newArrayList();
		for (String view : r.getLocattRules().keySet()) {
			PIDLocAttRule attRule = r.getLocattRules().get(view);
			if (attRule != null) {
				String resolveURLLocatt = "";
				Node resolveURLLocattNode = baseNode.selectSingleNode(attRule.getResolveURLXPath());
				if (!this.isBlank(resolveURLLocattNode))
					resolveURLLocatt = resolveURLLocattNode.getText();
				LocationType lt = new LocationType(resolveURLLocatt, view);
				locations.add(lt);
			}
		}
		return locations;
	}

	/**
	 * Checks if a Node is not null and if its text content is not blank (i.e., not a whitespace, empty ("") or null).
	 * 
	 * @param node
	 *            Node to check
	 * @return true if the Node is null, or if its text content is null, empty or whitespace
	 */
	public boolean isBlank(Node node) {
		return node == null || StringUtils.isBlank(node.getText());
	}

	/**
	 * Check if the text value in baseNode/xPath is not blank.
	 * 
	 * @param baseNode
	 *            Node where to apply the xPath
	 * @param xPath
	 *            String identifying an xpath to be applied to the base node
	 * @param objIdentifier
	 *            String identifier of the record at hand
	 * @return true if baseNode/xPath exists and its text value is not blank
	 */
	public boolean isNotBlank(Node baseNode, String xPath, String objIdentifier) {
		if (this.isBlank(baseNode.selectSingleNode(xPath))) {
			log.debug("Record objIdentifier: " + objIdentifier + ". baseNode: " + baseNode.getPath() + " : no node or value at path " + xPath);
			return false;
		}
		return true;
	}

	public String getResolveURL(Node baseNode, String resolveURLXPath) {
		if (StringUtils.isBlank(resolveURLXPath))
			return "";
		Node resolveURLNode = baseNode.selectSingleNode(resolveURLXPath);
		if (this.isBlank(resolveURLNode)) {
			log.fatal("Expected resolveURL not found in " + resolveURLXPath + ": using default " + this.getUnavailableURL());
			return this.getUnavailableURL();
		} else
			return resolveURLNode.getText();
	}

	public String getDerivative2URL(List<LocationType> locatts) {
		if (locatts == null)
			return this.unavailableURL;
		for (LocationType lt : locatts) {
			if (lt.getView().equals("level2"))
				return lt.getHref();
		}
		return this.unavailableURL;
	}

	public void setEmptyLocatts(PidType pid) {
		LocAttType locatt = new LocAttType();
		locatt.getLocation().addAll(Lists.newArrayList(new LocationType("", "level2"), new LocationType("", "level3")));
		pid.setLocAtt(locatt);
	}

	public PIDAssignerHelper() {
		super();
	}

	public PIDAssignerHelper(String unavailableURL) {
		this();
		this.unavailableURL = unavailableURL;
	}

	public String getUnavailableURL() {
		return unavailableURL;
	}

	public void setUnavailableURL(String unavailableURL) {
		this.unavailableURL = unavailableURL;
	}

}
