package eu.dnetlib.pid.service;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.socialhistoryservices.pid.LocationType;
import org.socialhistoryservices.pid.PidType;

import eu.dnetlib.enabling.tools.AbstractBaseService;
import eu.dnetlib.pid.service.rmi.PIDBridgeService;

/**
 * Implementation of the PIDServiceBridge. Forwards the incoming calls to the actual PID service outside the D-Net
 * infrastructure.
 * 
 * @author alessia
 * 
 */
public class PIDBridgeServiceImpl extends AbstractBaseService implements PIDBridgeService {

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

	private PidServiceClient pidServiceClient;

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#createPid()
	 */
	@Override
	public PidType createPid(final String namingAuthority) {
		log.debug("createPid(" + namingAuthority + ")");
		return this.pidServiceClient.createPid(namingAuthority);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#deletePids()
	 */
	@Override
	public int deletePids(final String namingAuthority) {
		log.debug("deletePids(" + namingAuthority + ")");
		return this.pidServiceClient.deletePids(namingAuthority);
	}

	@Override
	public void deleteListPids(final List<PidType> pidsToRemove) {
		log.debug("deletePid(" + pidsToRemove + ")");
		for (PidType pid : pidsToRemove) {
			this.pidServiceClient.deletePid(pid.getPid());
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#getPid()
	 */
	@Override
	public PidType getPid(final String pid) {
		log.debug("getPid(" + pid + ")");
		return this.pidServiceClient.getPid(pid);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#getPidByAttribute()
	 */
	@Override
	public List<PidType> getPidByAttribute(final String namingAuthority, final String attributeValue) {
		log.debug("getPidByAttribute(" + namingAuthority + ", " + attributeValue + ")");
		List<PidType> pids = this.pidServiceClient.getPidByAttribute(namingAuthority, attributeValue);
		log.debug(pids);
		return pids;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#getQuickPid()
	 */
	@Override
	public PidType getQuickPid(final String namingAuthority, final String localID, final String resolveURL) {
		log.debug("getQuickPid(" + namingAuthority + ", " + localID + ", " + resolveURL + ")");
		PidType p = this.pidServiceClient.getQuickPid(namingAuthority, localID, resolveURL);
		log.debug(p);
		return p;
	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#update(java.lang.String, java.lang.String, java.lang.String,
	 *      java.util.List)
	 */
	@Override
	public PidType update(final String pid, final String resolveURL, final String localID, final List<LocationType> locations) {
		log.debug("update(" + pid + ", " + resolveURL + ", " + localID + ", " + locations + ")");
		return this.pidServiceClient.update(pid, resolveURL, localID, locations);

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#isLocalIDBounded(java.lang.String, java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public boolean isLocalIDBounded(String namingAuthority, String localID) {
		List<PidType> res = this.getPidByAttribute(namingAuthority, localID);
		if (res.size() > 1)
			log.fatal("isLocalIDBounded got a list of "
					+ res.size()
					+ " PidType instead of 0 or 1. Please tell IISG the PID web service needs a method to check if a localID is already bounded (e.g., add attributeName parameter to the getPidByAttribute)");
		return res.size() > 0;
	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#reverseLookupByLocalID(java.lang.String, java.lang.String)
	 */
	@Override
	public PidType reverseLookupByLocalID(String namingAuthority, String localID) {
		List<PidType> res = this.getPidByAttribute(namingAuthority, localID);
		if (res != null) {
			if (res.size() > 1)
				log.fatal("reverseLookupByLocalID got a list of "
						+ res.size()
						+ " PidType instead of 0 or 1. Please tell IISG the PID web service needs a method to specify if we want the reverseLookup by localID or by resolveURL (e.g., add attributeName parameter to the getPidByAttribute)");
			if (res.size() >= 1)
				return res.get(0);
		}
		return null;
	}

	@Override
	public PidType reverseLookupByResolveURL(String namingAuthority, String resolveURL) {
		List<PidType> res = this.getPidByAttribute(namingAuthority, resolveURL);
		if (res.size() > 1)
			log.fatal("reverseLookupByResolveURL got a list of "
					+ res.size()
					+ " PidType instead of 0 or 1. Please tell IISG the PID web service needs a method to specify if we want the reverseLookup by localID or by resolveURL (e.g., add attributeName parameter to the getPidByAttribute)");
		if (res.size() >= 1)
			return res.get(0);
		else
			return null;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.pid.service.rmi.PIDBridgeService#updatePid(eu.consortiumservices.pid.PidType)
	 */
	@Override
	public PidType updatePid(final PidType pid) {
		log.debug("updatePid(" + pid + ")");
		return this.pidServiceClient.updatePid(pid);
	}

	@Override
	public PidType upsert(String namingAuthority, String pid, String resolveURL, String localID, List<LocationType> locations) {
		log.debug("upsert(" + namingAuthority + ", " + pid + ", " + resolveURL + ", " + localID + ", " + locations + ")");
		PidType p = this.pidServiceClient.upsert(namingAuthority, pid, resolveURL, localID, locations);
		log.debug(p);
		return p;
	}

	public void setPidServiceClient(final PidServiceClient pidServiceClient) {
		this.pidServiceClient = pidServiceClient;
	}

	public PidServiceClient getPidServiceClient() {
		return this.pidServiceClient;
	}

}
