package eu.dnetlib.client.updaters;

import java.util.logging.Logger;

import javax.inject.Inject;

import com.google.inject.Singleton;

import eu.dnetlib.client.managers.ActiveComponentsManager;
import eu.dnetlib.client.shared.StartUpComponents;
import eu.dnetlib.client.shared.TitleAndAlias;
import eu.dnetlib.efg1914.authoring.components.Configuration;
import eu.dnetlib.efg1914.authoring.components.Frame;
import eu.dnetlib.efg1914.authoring.components.Item;
import eu.dnetlib.efg1914.authoring.components.Theme;
import eu.dnetlib.efg1914.authoring.components.Topic;
import eu.dnetlib.efg1914.authoring.users.User;

@Singleton
public class Updater {
	@Inject
	private StartUpComponents startUpComponents;
	@Inject
	private LayoutUpdater layoutUpdater;
	@Inject
	private ActiveComponentsManager activeComponentsManager;
	private static Logger log = Logger.getLogger("Updater.java");

	@Inject
	Updater() {

	}

	public synchronized void createNewItem(final String userId, Item item, boolean isLocal) {

		if ((!isLocal) && startUpComponents.getAllItems().containsKey(item.getId())) {
			return;
		}
		TitleAndAlias.updateAliasMap(item.getId(), null, item.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllItems().put(item.getId(), item);
		layoutUpdater.addNewItem(userId, item, isLocal);

	}

	public synchronized void updateItem(final Item item, final String userId, boolean isLocal) {
		boolean inUse=false;
		if (!isLocal) {
			if (activeComponentsManager.isInUse(item.getId(), userId)) {
				// TODO ti kanume an ena item einai in use apo to xristi??
				// an erthei update apo ti basi ( thread tou component
				// loader) kai o user exei kapoio item anoixto kai to
				// kanei edit, tote den prepei na ginetai update
				// gia na min xasei tin proodo tou

				log.warning(" AAAAAAAAAAAAAAAA updating item that is currently in edit..");
				inUse=true;
//				startUpComponents.getAllItems().put(item.getId(), item);
//
//				return;
			}

		}
		String oldAlias=null;
		if(startUpComponents.getAllThemes().get(item.getId())!=null){
			oldAlias=startUpComponents.getAllThemes().get(item.getId()).getAlias();
		}
		TitleAndAlias.updateAliasMap(item.getId(), oldAlias, item.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllItems().put(item.getId(), item);

		layoutUpdater.updateItem(userId, item, isLocal, inUse);

	}

	public synchronized void deleteItem(final Item item, final String userId, boolean isLocal) {
		String itemID=item.getId();
		startUpComponents.getAllItems().remove(item.getId());
		if(startUpComponents.getAliasIds().get(item.getAlias())!=null&&startUpComponents.getAliasIds().get(item.getAlias()).equals(item.getId())){
			startUpComponents.getAliasIds().remove(item.getAlias());
		}
		layoutUpdater.removeDeletedItem(userId, item, isLocal);
		for(Frame f:startUpComponents.getAllFrames().values()){
			if(f.getItems().contains(itemID)){
				f.getItems().remove(itemID);
			}
		}
	}

	public synchronized void createNewFrame(final String userId, final Frame frame, boolean isLocal) {
		if ((!isLocal) && startUpComponents.getAllFrames().containsKey(frame.getId())) {
			return;
		}
		TitleAndAlias.updateAliasMap(frame.getId(), null, frame.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllFrames().put(frame.getId(), frame);
		layoutUpdater.addNewFrame(userId, frame, isLocal);

	}

	public synchronized void updateFrame(final Frame updatedFrame, final String userId, boolean isLocal) {
		boolean inUse=false;
		if (!isLocal) {
			if (activeComponentsManager.isInUse(updatedFrame.getId(), userId)) {
				log.warning(" AAAAAAAAAAAAAAAA updating updatedFrame  that is currently in edit..");
//				startUpComponents.getAllFrames().put(updatedFrame.getId(), updatedFrame);
//
//				return;
				inUse=true;
			}
		}
		String oldAlias=null;
		if(startUpComponents.getAllThemes().get(updatedFrame.getId())!=null){
			oldAlias=startUpComponents.getAllThemes().get(updatedFrame.getId()).getAlias();
		}
		TitleAndAlias.updateAliasMap(updatedFrame.getId(), oldAlias, updatedFrame.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllFrames().put(updatedFrame.getId(), updatedFrame);
		layoutUpdater.updateFrame(userId, updatedFrame, isLocal, inUse);

	}

	public synchronized void deleteFrame(final Frame frame, final String userId, boolean isLocal) {
		String frameId=frame.getId();
		startUpComponents.getAllFrames().remove(frame.getId());
		if(startUpComponents.getAliasIds().get(frame.getAlias())!=null&&startUpComponents.getAliasIds().get(frame.getAlias()).equals(frame.getId())){
			startUpComponents.getAliasIds().remove(frame.getAlias());
		}
		layoutUpdater.removeDeletedFrame(userId, frame, isLocal);
		for(Topic t:startUpComponents.getAllTopics().values()){
			if(t.getFrames().contains(frameId)){
				t.getFrames().remove(frameId);
			}
		}
	}

	public synchronized void createNewTopic(final String userId, final Topic newTopic, boolean isLocal) {
		if ((!isLocal) && startUpComponents.getAllTopics().containsKey(newTopic.getId())) {
			return;
		}
		TitleAndAlias.updateAliasMap(newTopic.getId(), null, newTopic.getAlias(), startUpComponents.getAliasIds());

		startUpComponents.getAllTopics().put(newTopic.getId(), newTopic);
		layoutUpdater.addNewTopic(userId, newTopic, isLocal);

	}

	public synchronized void updateTopic(final Topic updatedTopic, final String userId, boolean isLocal) {
		boolean inUse=false;

		if (!isLocal) {
			if (activeComponentsManager.isInUse(updatedTopic.getId(), userId)) {
				log.warning(" AAAAAAAAAAAAAAAA updating updatedTopic  that is currently in edit..");
//				startUpComponents.getAllTopics().put(updatedTopic.getId(), updatedTopic);
//
//				return;
				inUse=true;
			}
		}
		String oldAlias=null;
		if(startUpComponents.getAllTopics().get(updatedTopic.getId())!=null){
			oldAlias=startUpComponents.getAllTopics().get(updatedTopic.getId()).getAlias();
		}
		TitleAndAlias.updateAliasMap(updatedTopic.getId(), oldAlias, updatedTopic.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllTopics().put(updatedTopic.getId(), updatedTopic);
		layoutUpdater.updateTopic(userId, updatedTopic, isLocal, inUse);

	}

	public synchronized void deleteTopic(final Topic topic, final String userId, boolean isLocal) {
		String topicID=topic.getId();
		startUpComponents.getAllTopics().remove(topic.getId());
		if(startUpComponents.getAliasIds().get(topic.getAlias())!=null&&startUpComponents.getAliasIds().get(topic.getAlias()).equals(topic.getId())){
			startUpComponents.getAliasIds().remove(topic.getAlias());
		}
		layoutUpdater.removeDeletedTopic(userId, topic, isLocal);
		for(Theme theme:startUpComponents.getAllThemes().values()){
			if(theme.getTopics().contains(topicID)){
				theme.getTopics().remove(topicID);
			}
		}

	}

	public synchronized void createNewTheme(final String userId, final Theme newTheme, boolean isLocal) {
		if ((!isLocal) && startUpComponents.getAllThemes().containsKey(newTheme.getId())) {
			return;
		}
		//******
		 
		TitleAndAlias.updateAliasMap(newTheme.getId(), null, newTheme.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllThemes().put(newTheme.getId(), newTheme);
		layoutUpdater.addNewTheme(userId, newTheme, isLocal);

	}

	public synchronized void updateTheme(final Theme updatedTheme, final String userId, boolean isLocal) {
		boolean inUse=false;

		if (!isLocal) {
			if (activeComponentsManager.isInUse(updatedTheme.getId(), userId)) {
				log.warning(" AAAAAAAAAAAAAAAA updating updatedTheme  that is currently in edit..");
//				startUpComponents.getAllThemes().put(updatedTheme.getId(), updatedTheme);
//				return;
				inUse=true;
			}
		}
		String oldAlias=null;
		if(startUpComponents.getAllThemes().get(updatedTheme.getId())!=null){
			oldAlias=startUpComponents.getAllThemes().get(updatedTheme.getId()).getAlias();
		}
		TitleAndAlias.updateAliasMap(updatedTheme.getId(), oldAlias, updatedTheme.getAlias(), startUpComponents.getAliasIds());
		
		startUpComponents.getAllThemes().put(updatedTheme.getId(), updatedTheme);
		layoutUpdater.updateTheme(userId, updatedTheme, isLocal, inUse);

	}

	public synchronized void deleteTheme(final Theme theme, final String userId, boolean isLocal) {
		startUpComponents.getAllThemes().remove(theme.getId());
		if(startUpComponents.getAliasIds().get(theme.getAlias())!=null&&startUpComponents.getAliasIds().get(theme.getAlias()).equals(theme.getId())){
			startUpComponents.getAliasIds().remove(theme.getAlias());
		}
		layoutUpdater.deleteTheme(userId, theme, isLocal);

	}

	public synchronized void createUser(final User userToCreate, final String userId, boolean isLocal) {

		startUpComponents.getCurators().put(userToCreate.getId(), userToCreate.getUsername());

		layoutUpdater.addNewUser(userId, userToCreate, isLocal);

	}

	public synchronized void updateUser(final User userToUpdate, final String userId, boolean isLocal) {
		boolean inUse=false;
		if ((!isLocal) && activeComponentsManager.isInUse(userToUpdate.getId(), userId)) {
			inUse=true;
//			return;
		}

		startUpComponents.getCurators().put(userToUpdate.getId(), userToUpdate.getUsername());

		if (startUpComponents.getUser().getId().equals(userToUpdate.getId())) {
			startUpComponents.setUser(userToUpdate);
		}

		layoutUpdater.updateUser(userId, userToUpdate, isLocal, inUse);

	}

	public synchronized void deleteUser(final String userIdToDelete, final String userId, boolean isLocal) {

		startUpComponents.getCurators().remove(userIdToDelete);
		layoutUpdater.removeDeletedUser(userId, userIdToDelete, isLocal);

	}
	
 
	public synchronized void updateConfiguration(Configuration configuration, final String userId, boolean isLocal) {
		startUpComponents.setConfiguration(configuration);
		layoutUpdater.updateConfiguration(userId, configuration, isLocal);
	}
	
	
	//Failures
	
	public void itemFails(boolean isLocal){
		layoutUpdater.itemFails(isLocal);
	}
	public void frameFails(boolean isLocal){
		layoutUpdater.frameFails(isLocal);
	}
	public void topicFails(boolean isLocal){
		layoutUpdater.topicFails(isLocal);
	}
	public void themeFails(boolean isLocal){
		layoutUpdater.themeFails(isLocal);
	}
	public void userFails(boolean isLocal){
		layoutUpdater.usersFails(isLocal);
	}
	public void configurationFails(boolean isLocal){
		layoutUpdater.configurationFails(isLocal);
	}
 
}
