/**
 * 
 */
package eu.dnetlib.download.plugin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.gson.Gson;

import eu.dnetlib.data.download.rmi.AbstractDownloadPlugin;
import eu.dnetlib.data.download.rmi.DownloadItem;
import eu.dnetlib.data.download.rmi.DownloadPlugin;
import eu.dnetlib.data.download.rmi.DownloadPluginException;

/**
 * The Signposting plugin supports the Publication Boundary Pattern in order to use the fulltext url for download.
 * @author jochen
 *
 */
public class SignpostingPlugin extends AbstractDownloadPlugin implements DownloadPlugin{

    /**
     * The Constant log.
     */
    private static final Log log = LogFactory.getLog(SignpostingPlugin.class);

	/* (non-Javadoc)
	 * @see eu.dnetlib.data.download.rmi.AbstractDownloadPlugin#extractURL(java.lang.String)
	 */
	@Override
	public String extractURL(String url) throws DownloadPluginException {
		try{
			Builder config = RequestConfig.custom()
					.setConnectionRequestTimeout(AbstractDownloadPlugin.DEFAULT_TIMEOUT)
					.setConnectTimeout(AbstractDownloadPlugin.DEFAULT_TIMEOUT)
					.setSocketTimeout(AbstractDownloadPlugin.DEFAULT_TIMEOUT);
			
	        HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(config.build()) .build();
	        HttpGet request = new HttpGet(url);
	        HttpResponse response = client.execute(request);
	        log.debug("status code: " + response.getStatusLine().getStatusCode());
	        Header[] links = response.getHeaders("Link");
	        Iterator<Header> iterator = Arrays.asList(links).iterator();
	        while(iterator.hasNext()){
	        	Iterator<HeaderElement> iteratorElements = Arrays.asList(iterator.next().getElements()).iterator();
	        	String name = "";
	        	while(iteratorElements.hasNext()){
	        		HeaderElement element = iteratorElements.next();
	        		name = element.getName();
	        		NameValuePair[] nvPair = element.getParameters();
		        	String rel = "";
		        	String type = "";
	        		for (int j = 0; j < nvPair.length; j++){
	        			if (nvPair[j].getName().equals("rel") && nvPair[j].getValue().equals("item"))
	        					rel = "item";
	        			if (nvPair[j].getName().equals("type") && nvPair[j].getValue().equals("application/pdf"))
	        				type = "application/pdf";
	        			log.debug("param name: " + nvPair[j].getName() + " param value: " + nvPair[j].getValue());
	        		}
	        		if (rel.equals("item") && type.equals("application/pdf"))
	        			return name.replaceAll("^<|>$", "");
	        	}
	        }
		}catch(Throwable e){
	        throw new DownloadPluginException("Error on extract URL", e);			
		}
		
		return null;
	}

	@Override
	public String getPluginName() {
		return "SignpostingPlugin";
	}

	@Override
	public DownloadItem retrieveUrl(DownloadItem input) throws DownloadPluginException {
        if (checkOpenAccess(input) == null) return null;
        String url = input.getOriginalUrl();

        if ((url == null) || (url.trim().length() == 0)) return input;
        @SuppressWarnings("unchecked")
        List<String> urls = new Gson().fromJson(url, ArrayList.class);
        if ((urls == null) || (urls.size() == 0)) return input;
        if (checkUrlsNotNull(input, urls))
            return input;
        input.setOriginalUrl(null);
        input.setUrl(null);
        return input;
	}

	@Override
	public Iterable<DownloadItem> retrieveUrls(Iterable<DownloadItem> urls) throws DownloadPluginException {
        return Iterables.transform(urls, new Function<DownloadItem, DownloadItem>() {

            @Override
            public DownloadItem apply(final DownloadItem input) {
                return retrieveUrl(input);
            }
        });
	}

	@Override
	public void setBasePath(String arg0) {
		// TODO Auto-generated method stub
		
	}

}
