package eu.dnetlib.wds.resolver;


import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import eu.dnetlib.pid.resolver.AbstractPIDResolver;
import eu.dnetlib.pid.resolver.model.ObjectProvenance;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;

public class OpenAireResolver extends AbstractPIDResolver {

    private final static String templateURL = "pid:\"%s\"";
    private final static String OPENAIRE_NS_PREFIX = "openaire____";
    private final static String baseURL = "http://solr.openaire.eu:8983/solr/DMF-index-openaire_shard1_replica1/select?q=%s&wt=json";

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


    private final OpenAireParser parser = new OpenAireParser();


    @Override
    protected boolean canResolvePid(final String pidType) {
        return (pidType != null && pidType.toLowerCase().equals("doi"));
    }

    @Override
    protected WDSResolvedObject resolve(final String pid, final String pidType) {
        try {
            final String currentQuery = String.format(baseURL, URLEncoder.encode(String.format(templateURL, pid), "UTF-8"));
            WDSResolvedObject obj = parsingResponse(requestURL(currentQuery));
            if (obj == null)
                return null;
            obj.setPidType(pidType);
            obj.setPid(pid);
            return obj;
        } catch (Throwable e) {
            log.error("Error on resolve pid " + pid, e);
        }
        return null;
    }

    private WDSResolvedObject parsingResponse(final String response) {
        if (response == null) return null;
        final JsonElement jElement = new JsonParser().parse(response);
        final JsonObject jobject = jElement.getAsJsonObject();
        if (jobject.has("response")) {
            long total = jobject.get("response").getAsJsonObject().get("numFound").getAsLong();
            if (total == 0) return null;
            JsonArray hits = ((JsonObject) jobject.get("response")).get("docs").getAsJsonArray();
            JsonElement s = ((JsonObject) hits.get(0)).get("__result").getAsJsonArray().get(0);
            final WDSResolvedObject resolvedObject = parser.parseObject(s.getAsString());
            resolvedObject.setRelations(Lists.newArrayList());
            final ObjectProvenance op = new ObjectProvenance();
            op.setDatasource("OpenAIRE");
            op.setDatasourceId("wds_________::openaire");
            resolvedObject.setDatasourceProvenance(Collections.singletonList(op));
            return resolvedObject;
        }
        return null;
    }
}
