package eu.dnetlib.dli.resolver;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.QueryBuilder;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import eu.dnetlib.dli.resolver.model.DLIResolvedObject;
import eu.dnetlib.dli.resolver.model.DLIResolvedObjectDeserializer;
import eu.dnetlib.pid.resolver.AbstractPIDResolver;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.beans.factory.annotation.Autowired;

public class DLIOfflineResolver extends AbstractPIDResolver {

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

    @Autowired
    private MongoClient mongoClient;

    private MongoDatabase db;

    private Gson g = new GsonBuilder().registerTypeAdapter(DLIResolvedObject.class, new DLIResolvedObjectDeserializer()).create();

    @Override
    protected boolean canResolvePid(final String pidType) {
//        return isAvailableOffline();
        return true;
    }

    @Override
    protected DLIResolvedObject resolve(final String pid, final String pidType) {

        final String dliItem = retrieveDLIFromDump(pid.toLowerCase().trim(),pidType.toLowerCase().trim());
        if (dliItem!= null)
            return g.fromJson(dliItem, DLIResolvedObject.class);
        return null;

    }


    private String retrieveDLIFromDump(final String pid, final String pidType) {
        log.debug(String.format("trying to find %s of type %s", pid, pidType));
        if (db == null) {
            db = mongoClient.getDatabase("dli_resolved");
        }
        final MongoCollection<Document> crossRef = db.getCollection("dli");
        DBObject query = QueryBuilder.start("pid").is(pid).and("pid_type").is(pidType).get();
        FindIterable<Document> documents = crossRef.find((Bson) query).limit(1);
        MongoCursor<Document> iterator = documents.iterator();
        if (iterator.hasNext()){
            log.debug("found pid "+pid);
            return iterator.next().get("body").toString();
        }
        return null;
    }


}
