package eu.dnetlib.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import eu.dnetlib.client.GreetingService;
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.Permit;
import eu.dnetlib.efg1914.authoring.components.Theme;
import eu.dnetlib.efg1914.authoring.components.Topic;
import eu.dnetlib.efg1914.authoring.managers.ComponentManager;
import eu.dnetlib.efg1914.authoring.managers.ComponentManagerException;
import eu.dnetlib.efg1914.authoring.managers.MediaManager;
import eu.dnetlib.efg1914.authoring.managers.UserManager;
import eu.dnetlib.efg1914.authoring.managers.UserManagerException;
import eu.dnetlib.efg1914.authoring.users.User;
import eu.dnetlib.efg1914.commons.store.MediaStoreException;
import eu.dnetlib.efg1914.commons.store.XMLStoreException;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
@Service("greetingService")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {
	@Autowired
	private ComponentManager componentManager;
	@Autowired
	private MediaManager mediaManager;
	@Autowired
	private UserManager userManager;

	private static Logger log = Logger.getLogger("greetingServiceImpl");

	public String sendItemServer(Item item) throws XMLStoreException {
		String id = item.getTitle();
		return id;
	}

	/*************************
	 * GET COMPONENTS FROM DB ON STARTUP
	 * 
	 * @throws XMLStoreException
	 * *********************************/

	public GreetingServiceImpl() {

	}

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

	public Item createNewItem(User user, Item itemToSave) throws XMLStoreException {
		try {
			log.info(" Create   new   ITEM!! ");
			Item it = this.componentManager.createNewItem(itemToSave);

			log.info(" CREATED ITEM id: " + it.getId());

			return it;
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}

	}

	public Item fetchItemMetadata(String url) throws XMLStoreException {
		try {
			return this.componentManager.fetchItemMetadata(url);
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException();
		}

	}
 	public   Item fetchIVideoMetadata(String url)  {
		  return this.componentManager.fetchVideoMetadata(url);

	}
	
	public Item createNewImageItemFromID(User user, String url, String filetype, String mediaID) throws XMLStoreException {

		try {
			log.info(" Create   new   ITEM!! ");
			Item it = this.componentManager.createNewImageItem(user, url, filetype, mediaID);

			log.info(" CREATED ITEM id: " + it.getId());

			return it;
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}

	}

	public Item createNewVideoItem(User user, String filetype, String url, String mediaId) throws XMLStoreException {
		log.info(" Create  new ITEM from metadata !! ");

		try {
			Item it = this.componentManager.createNewVideoItem(user, filetype, url, mediaId);
			log.info("CREATED ITEM id: " + it.getId());
			return it;
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}

	}

	public ArrayList<Item> getAllItems() throws XMLStoreException {

		try {
			ArrayList<Item> items = this.componentManager.getAllItems();

			return items;
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}

	}

	public Item getItemById(String itemId) throws XMLStoreException {
		log.info("Get  ITEM!! ");

		try {
			Item item = this.componentManager.getItem(itemId);
			return item;
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}
	}

	public boolean updateItemMetadata(Item item) throws XMLStoreException {
		log.info("Update ITEM   !! ");

		try {
			return this.componentManager.updateItem(item);
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}

	}

	public String deleteItem(Item item) throws XMLStoreException {
		log.info(" Removing ITEM   !! ");

		try {
			this.componentManager.deleteItem(item);
		} catch (ComponentManagerException e) {
			log.warning("couldn't update users num ");
			throw new XMLStoreException(e);
		}
		return "done";
	}

	public String deleteMedia(String mediaId) throws XMLStoreException {
		log.info(" Removing ITEM MEDIA !! " + mediaId);
		try {
			this.mediaManager.deleteMediaFile(mediaId);
		} catch (MediaStoreException e) {

			e.printStackTrace();
			throw new XMLStoreException("   delete Media  failed " + e.toString());
		}

		return "done";
	}

	public Item updateItem(Item item) throws XMLStoreException {
		log.info("Update  whole Item ! ");

		try {
			this.componentManager.updateItem(item);
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException("Item and thumb update failed " + e.toString());
		}

		return item;

	}

	public Item updateItem(Item item, String miniId, String mediumId, String thumbFileType, boolean isThumbChanged) throws XMLStoreException {

		log.info("Update   Item  with new images! ");

		try {

			if (isThumbChanged)

			{

				if (miniId == null || miniId.isEmpty()) {
					log.info("Without mini ");

				}
				if (mediumId == null || mediumId.isEmpty()) {
					log.info("Without medium ");

				}
				item.setMediumImage(mediumId);
				item.setMiniImage(miniId);

			}

			this.componentManager.updateItem(item);

		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException("Item and thumb update failed");

		}
		return item;

	}

	public List<String> getItemParents(String itemId) throws XMLStoreException {
		return this.componentManager.getItemParentsIds(itemId);

	}

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

	public String saveFrame(Frame frame) throws XMLStoreException {
		log.info("Save Frame!!");
		try {
			return this.componentManager.saveFrame(frame);
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public List<Frame> getAllFrames() throws XMLStoreException {
		System.out.println("Get my ITEMs!! ");

		try {
			return this.componentManager.getAllFrames();

		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public Frame getFrameById(String frameId) throws XMLStoreException {
		System.out.println("Get my frame!! ");

		try {
			return this.componentManager.getFrame(frameId);

		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public String updateFrame(Frame frame) throws XMLStoreException {
		log.info("update frame ! ");

		try {
			this.componentManager.updateFrame(frame);
			return frame.getId();
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public String deleteFrame(String frameId) throws XMLStoreException {
		log.info("delete frame ! ");

		try {
			this.componentManager.deleteFrame(frameId);
			return "ok";
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public List<String> getFrameParents(String frameId) throws XMLStoreException {
		return this.componentManager.getFrameParentsIds(frameId);
	}

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

	public String saveTopic(Topic topic) throws XMLStoreException {

		try {
			return componentManager.saveTopic(topic);
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public Topic saveAndGetTopic(Topic topic) throws XMLStoreException {

		try {
			String newTopicId = componentManager.saveTopic(topic);

			return componentManager.getTopic(newTopicId);
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}
	}

	public String updateTopic(Topic t) throws XMLStoreException {

		try {
			componentManager.updateTopic(t);
			return " ok ";
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public String deleteTopic(String topicId) throws XMLStoreException {

		try {
			componentManager.deleteTopic(topicId);
			return " ok ";
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public List<String> getTopicParents(String topicId) throws XMLStoreException {
		return this.componentManager.getTopicParentsIds(topicId);
	}

	/*******************************************************
	 * THEMES
	 ******************************************************/
	public Theme saveTheme(Theme theme) throws XMLStoreException {

		try {
			String themeId = componentManager.saveTheme(theme);
			return componentManager.getTheme(themeId);
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public String updateTheme(Theme theme) throws XMLStoreException {
		try {					
			log.warning("------------------****#################Update theme!!!!!!!!!");
			HttpServletRequest request = this.getThreadLocalRequest();
			if (request != null) {
				// dont create a new one -> false
				HttpSession session = request.getSession(false);
				if (session != null) {
					Object userObj = session.getAttribute("UserID");
					if (userObj != null && userObj instanceof User) {
						log.warning("------------------****#################3 valid:true");
					}else{
						log.warning("------------------****#################3 user:::false");
					}
				}else{
					log.warning("------------------****#################3 session:::NULL");
				}
			}else{
				log.warning("------------------****#################3 request:::NULL");
			}
			log.warning("------------------****#################3 valid:---");

			componentManager.updateTheme(theme);
			return " ok ";
		} catch (ComponentManagerException e) {
			e.printStackTrace();
			log.warning("------------------****exception while updating theme  " + e.getMessage());
			throw new XMLStoreException(e);
		}

	}

	public String deleteTheme(Theme theme) throws XMLStoreException {

		try {
			componentManager.deleteTheme(theme);
			return " ok ";
		} catch (ComponentManagerException e) {
			e.printStackTrace();

			throw new XMLStoreException(e);
		}

	}

	/*******************************************************
	 * USER MANAGEMENT
	 * 
	 * @throws XMLStoreException
	 ******************************************************/

	public HashMap<String, Permit> loadPermissions(String username) throws XMLStoreException {

		try {
			return userManager.loadPermissions(username);

		} catch (UserManagerException e) {

			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public void registerUser(User user) throws XMLStoreException {
		log.info("Attempting to create new user..!!");

		try {
			this.userManager.registerUser(user);

		} catch (UserManagerException e) {
			throw new XMLStoreException("User registration for " + user.getUsername() + "failed", e);
		}

	}

	public String updateUser(User user) throws XMLStoreException {
		log.info("updating user..!!");

		try {
			this.userManager.updateUser(user);
			return "ok";
		} catch (UserManagerException e) {
			throw new XMLStoreException(e);
		}

	}

	public String getUserName(String userId) throws XMLStoreException {
		log.info("updating user..!!");

		try {
			return this.userManager.getCurator(userId);

		} catch (UserManagerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new XMLStoreException(e);
		}

	}

	public String saveUser(User user) throws UserManagerException {
		return userManager.saveUser(user);

	}

	public User getUserById(String userId) throws UserManagerException {
		return this.userManager.getUserById(userId);

	}

	/*
	 * Configuration
	 */
	public void updateConfiguration(Configuration configuration) throws ComponentManagerException {
		componentManager.updateConfiguration(configuration);
	}

	// TODO configuration
	public Configuration getConfigurationByName(String name) {
		try {
			return this.componentManager.getConfigurationByName(name);

		} catch (ComponentManagerException cme) {
			log.warning("Fail to get configuration." + cme.getMessage());
		}
		return null;
	}

	public void deleteUser(String userId) throws UserManagerException {
		this.userManager.deleteUser(userId);
	}

	@Deprecated
	public List<Theme> getPublishedThemes() {
		return this.componentManager.getPublishedThemes();
	}

	public ArrayList<String> getRoleNames() throws UserManagerException {
		return userManager.getRoleNames();
	}

}
