package eu.dnetlib.data.objectstore.modular;

import java.util.List;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.springframework.beans.factory.annotation.Required;

import com.google.gson.Gson;

import eu.dnetlib.data.objectstore.rmi.ObjectStoreFile;
import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
import eu.dnetlib.data.objectstore.rmi.ObjectStoreServiceException;
import eu.dnetlib.enabling.tools.AbstractBaseService;
import eu.dnetlib.enabling.tools.blackboard.NotificationHandler;

// TODO: Auto-generated Javadoc
/**
 * The Class ModularObjectStoreService is the implementation of the ObjectStoreService interface.
 */
public class ModularObjectStoreService extends AbstractBaseService implements ObjectStoreService {

	/** The feeder. */
	private ModularObjectStoreFeeder feeder;

	/** The object store deliver. */
	private ModularObjectStoreDeliver objectStoreDeliver;

	/** The notification handler. */
	private NotificationHandler notificationHandler;

	/*
	 * (non-Javadoc)
	 * 
	 * @see eu.dnetlib.data.objectstore.rmi.ObjectStoreService#deliverObjects(java.lang.String, java.lang.Double, java.lang.Double)
	 */
	/**
	 * Deliver objects.
	 *
	 * @param obsId
	 *            the obs id
	 * @param from
	 *            the from
	 * @param until
	 *            the until
	 * @return the w3 c endpoint reference
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	@Override
	public W3CEndpointReference deliverObjects(final String obsId, final Long from, final Long until) throws ObjectStoreServiceException {

		return objectStoreDeliver.deliver(obsId, from, until);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see eu.dnetlib.data.objectstore.rmi.ObjectStoreService#deliverObjectsByIds(java.lang.String,
	 * javax.xml.ws.wsaddressing.W3CEndpointReference)
	 */
	/**
	 * Deliver objects by ids.
	 *
	 * @param obsId
	 *            the obs id
	 * @param eprId
	 *            the epr id
	 * @return the w3 c endpoint reference
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	@Override
	public W3CEndpointReference deliverObjectsByIds(final String obsId, final W3CEndpointReference eprId) throws ObjectStoreServiceException {
		return objectStoreDeliver.deliverIds(obsId, eprId);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see eu.dnetlib.data.objectstore.rmi.ObjectStoreService#deliverRecord(java.lang.String, java.lang.String)
	 */
	/**
	 * Deliver record.
	 *
	 * @param obsId
	 *            the obs id
	 * @param objectId
	 *            the object id
	 * @return the string
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	@Override
	public String deliverRecord(final String obsId, final String objectId) throws ObjectStoreServiceException {
		return objectStoreDeliver.deliverObject(obsId, objectId).toJSON();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see eu.dnetlib.data.objectstore.rmi.ObjectStoreService#getListOfObjectStores()
	 */
	/**
	 * Gets the list of object stores.
	 *
	 * @return the list of object stores
	 */
	@Override
	public List<String> getListOfObjectStores() {
		return objectStoreDeliver.getDao().listObjectStores();
	}

	/**
	 * Gets the feeder.
	 *
	 * @return the feeder
	 */
	public ModularObjectStoreFeeder getFeeder() {
		return feeder;
	}

	/**
	 * Sets the feeder.
	 *
	 * @param feeder
	 *            the new feeder
	 */
	@Required
	public void setFeeder(final ModularObjectStoreFeeder feeder) {
		this.feeder = feeder;
	}

	/**
	 * Gets the notification handler.
	 *
	 * @return the notification handler
	 */
	public NotificationHandler getNotificationHandler() {
		return notificationHandler;
	}

	/**
	 * Sets the notification handler.
	 *
	 * @param notificationHandler
	 *            the new notification handler
	 */
	@Required
	public void setNotificationHandler(final NotificationHandler notificationHandler) {
		this.notificationHandler = notificationHandler;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see eu.dnetlib.enabling.tools.AbstractBaseService#notify(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public void notify(final String subscriptionId, final String topic, final String isId, final String message) {
		getNotificationHandler().notified(subscriptionId, topic, isId, message);
	}

	/**
	 * Gets the object store deliver.
	 *
	 * @return the object store deliver
	 */
	public ModularObjectStoreDeliver getObjectStoreDeliver() {
		return objectStoreDeliver;
	}

	/**
	 * Sets the object store deliver.
	 *
	 * @param objectStoreDeliver
	 *            the new object store deliver
	 */
	@Required
	public void setObjectStoreDeliver(final ModularObjectStoreDeliver objectStoreDeliver) {
		this.objectStoreDeliver = objectStoreDeliver;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see eu.dnetlib.data.objectstore.rmi.ObjectStoreService#feedObject(java.lang.String, java.lang.String)
	 */
	/**
	 * Feed object.
	 *
	 * @param obsId
	 *            the obs id
	 * @param objectMetadata
	 *            the object metadata
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	@Override
	public void feedObject(final String obsId, final String objectMetadata) throws ObjectStoreServiceException {
		Gson g = new Gson();
		try {
			ObjectStoreFile file = g.fromJson(objectMetadata, ObjectStoreFile.class);
			feeder.feedObject(obsId, file.getObjectID(), file.getURI(), file.getAccessProtocol(), file.getUsernameAuth(), file.getPasswordAuth(),
					file.getMimeType());

		} catch (Exception e) {
			throw new ObjectStoreServiceException(e.getMessage());
		}

	}

	/**
	 * Exist id starts with.
	 *
	 * @param obsId
	 *            the obs id
	 * @param startId
	 *            the start id
	 * @return true, if successful
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	public boolean existIDStartsWith(final String obsId, final String startId) throws ObjectStoreServiceException {
		return objectStoreDeliver.existIDStartsWith(obsId, startId);
	}

	/**
	 * Feed object.
	 *
	 * @param obsId
	 *            the obs id
	 * @param record
	 *            the record
	 * @return the string
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	public String feedObject(final String obsId, final ObjectStoreRecord record) throws ObjectStoreServiceException {

		try {

			return feeder.feedObjectRecord(obsId, record);

		} catch (Exception e) {
			throw new ObjectStoreServiceException(e.getMessage());
		}

	}

	/**
	 * Gets the size.
	 *
	 * @param obsId
	 *            the obs id
	 * @return the size
	 * @throws ObjectStoreServiceException
	 *             the object store service exception
	 */
	@Override
	public int getSize(final String obsId) throws ObjectStoreServiceException {
		return objectStoreDeliver.getDao().getObjectStore(obsId).getSize();

	}
}
