package eu.dnetlib.openaire.api;

import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Required;

import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

import eu.dnetlib.miscutils.datetime.DateUtils;

/**
* Created by michele on 11/11/15.
*/
public class RecentPublicationsQueue implements Iterable<String> {

	private static final Log log = LogFactory.getLog(RecentPublicationsQueue.class);

	private DB db;
	private String collection;

	public void init() {
		if (!db.collectionExists(collection)) {
			log.info(String.format("creating collection %s", collection));
			db.createCollection(collection, new BasicDBObject());
		}
	}

	@Override
	public Iterator<String> iterator() {

		final DBCursor cursor = db.getCollection(collection).find();

		return new Iterator<String>() {

			@Override
			public boolean hasNext() {
				return cursor.hasNext();
			}

			@Override
			public String next() {
				final DBObject obj = cursor.next();
				return ((obj != null) && obj.containsField("record")) ? obj.get("record").toString() : "";
			}

			@Override
			public void remove() {
				throw new RuntimeException("NOT IMPLEMENTED");
			}
		};
	}

	synchronized public void add(final String oaf) throws Exception {
		final String id = (new SAXReader()).read(new StringReader(oaf)).valueOf("//*[local-name() = 'objIdentifier']");

		log.info("Saving record " + id + " in db: " + db.getName() + ", coll: " + collection);

		final DBCollection coll = db.getCollection(collection);
		final DBObject obj = BasicDBObjectBuilder.start()
				.append("id", id)
				.append("record", oaf)
				.append("date", DateUtils.now())
				.get();
		coll.update(new BasicDBObject("id", id), obj, true, false);
	}

	public void remove(final List<String> list) {
		final DBCollection coll = db.getCollection(collection);
		for (final String id : list) {
			coll.remove(new BasicDBObject("id", id));
		}
	}

	public DB getDb() {
		return db;
	}

	@Required
	public void setDb(final DB db) {
		this.db = db;
	}

	public String getCollection() {
		return collection;
	}

	@Required
	public void setCollection(final String collection) {
		this.collection = collection;
	}
}
