package eu.dnetlib.server.notification;

import de.novanic.eventservice.client.event.Event;
import de.novanic.eventservice.client.event.domain.DomainFactory;
import de.novanic.eventservice.service.RemoteEventServiceServlet;
import eu.dnetlib.client.notification.NotificationEvent;
import eu.dnetlib.client.shared.Data;
import eu.dnetlib.efg1914.authoring.components.*;
import eu.dnetlib.efg1914.authoring.users.User;
import eu.dnetlib.server.ComponentsRegistry;
import eu.dnetlib.server.NotificationRegistry;

import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;

//import org.mortbay.log.Log;

public class NotificationServiceImpl extends RemoteEventServiceServlet { //implements NotificationService {
	private static Timer myEventGeneratorTimer;
	// private static final Domain COMET_DOMAIN;
	private static Logger log = Logger.getLogger("NotificationServiceImpl.java");

	private NotificationRegistry registry;
	/**
	 * 
	 */
	private static final long serialVersionUID = -2688286773001155929L;
	public final String userDomain = null;

	public NotificationServiceImpl() {
		registry = new ComponentsRegistry();
		myEventGeneratorTimer = new Timer();

		myEventGeneratorTimer.schedule(new updateComponents(), 500, 1000);
	};


	static {
		// COMET_DOMAIN = DomainFactory.getDomain(CometEvent.COMET_DOMAIN
		// .toString());

	}

	public void register(String userDomain) {

		this.registry.registerUser(userDomain);
		//Log.info("registred in comet !!");

	}
 	public void logout(String userId, ArrayList<String> userLockedComponents) {

		this.registry.removeUser(userId,userLockedComponents);

	}

	@Override
	public void destroy() {
		super.destroy();
		if (myEventGeneratorTimer != null) {
			// clean-up
			myEventGeneratorTimer.cancel();
			myEventGeneratorTimer.purge();
			registry.destroy();

		}

	}

	private class updateComponents extends TimerTask {

		public synchronized void run() {

			// create the event

			if (registry.getRegisteredUsers().entrySet() != null && !registry.getRegisteredUsers().entrySet().isEmpty()) {
				for (java.util.Map.Entry<String, Date> user : registry.getRegisteredUsers().entrySet()) {

					Data results = registry.receiveUpdates(user.getKey());

					Event theEvent = new NotificationEvent(results);

					addEvent(DomainFactory.getDomain(user.getKey()), theEvent);

				}
				// TODO lookup cache clear again

				registry.clearUpCache();
			}
		}
	}

	/******************
	 * 
	 * Active Components
	 * 
	 *****************/
	public void markComponent(String componentId, String userId) {

		this.registry.markComponent(componentId, userId);

	}

	public void unmarkComponent(String componentId, String userId) {

		this.registry.unmarkComponent(componentId, userId);

	}

	// *******************************
	// ITEMS
	// *******************************

	public void addItem(Item it) {

		this.registry.addItem(it);

	}

	public void deleteItem(Item it) {

		this.registry.addDeletedItem(it);
	}

	public void updateItem(Item it) {

		this.registry.addUpdatedItem(it);
	}

	// *******************************
	// FRAMES
	// *******************************

	public void addFrame(Frame it) {

		this.registry.addFrame(it);

	}

	public void deleteFrame(Frame id) {

		this.registry.addDeletedFrame(id);
	}

	public void updateFrame(Frame it) {

		this.registry.addUpdatedFrame(it);
	}

	// *******************************
	// TOPICS
	// *******************************

	public void addTopic(Topic it) {

		this.registry.addTopic(it);

	}

	public void deleteTopic(Topic id) {

		this.registry.addDeletedTopic(id);
	}

	public void updateTopic(Topic it) {

		this.registry.addUpdatedTopic(it);
	}

	// *******************************
	// THEME
	// *******************************

	public void addTheme(Theme it) {

		this.registry.addTheme(it);
	}

	public void deleteTheme(Theme id) {

		this.registry.addDeletedTheme(id);
	}

	public void updateTheme(Theme it) {

		this.registry.addUpdatedTheme(it);

	}

	public String getUserDomain() {
		return userDomain;
	}

	public void addUser(User user) {
		this.registry.addUser(user);

	}

	public void updateUser(User user) {
		this.registry.addUpdatedUser(user);

	}

	public void deleteUser(String userId) {
		this.registry.addDeletedUser(userId);

	}

	public void clearActive() {
		this.registry.clearActive();

	}

	public void clearActiveByUser(String userId, ArrayList<String> userLockedComponents) {
		this.registry.clearActive(userId,userLockedComponents);

	}

	public void updateConfiguration(Configuration configuration) {
		this.registry.updateConfiguration(configuration);

	}
}
