/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.vaaclipse.addons.softwarefactory.service;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.contexts.RunAndTrack;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.translation.TranslationService;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MBindingContext;
import org.eclipse.e4.ui.model.application.commands.MBindingTable;
import org.eclipse.e4.ui.model.application.commands.impl.CommandsFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.impl.AdvancedFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow;
import org.eclipse.e4.ui.model.application.ui.basic.impl.BasicFactoryImpl;
import org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
import org.eclipse.e4.ui.model.application.ui.menu.impl.MenuFactoryImpl;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.osbp.core.api.persistence.IPersistenceException;
import org.eclipse.osbp.core.api.persistence.IPersistenceService;
import org.eclipse.osbp.core.api.persistence.PersistenceExceptionEvent;
import org.eclipse.osbp.datainterchange.api.IDataInterchange;
import org.eclipse.osbp.dsl.metadata.service.DSLBuilderParticipant.DSLMetadataService;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.eventbroker.EventDispatcher;
import org.eclipse.osbp.persistence.PersistenceService;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.report.ReportProvider;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.runtime.common.i18n.II18nService;
import org.eclipse.osbp.ui.api.contextfunction.ICommandsProvider;
import org.eclipse.osbp.ui.api.contextfunction.IDashboardProvider;
import org.eclipse.osbp.ui.api.message.IMessageRequester;
import org.eclipse.osbp.ui.api.message.MessageEvent;
import org.eclipse.osbp.ui.api.message.MessageEvent.EventType;
import org.eclipse.osbp.ui.api.message.MessageRequesterEvent;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.common.helper.ICommonUIHelper;
import org.eclipse.osbp.ui.common.helper.impl.CommonUIHelper;
import org.eclipse.osbp.utils.vaadin.MessageDialog;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.handler.I18NHandler;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.handler.PrintServiceHandler;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.handler.ThemeHandler;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.handler.UserHandler;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.perspective.PerspectiveProvider;
import org.eclipse.osbp.vaaclipse.addons.softwarefactory.welcome.WelcomeView;
import org.eclipse.osbp.vaaclipse.common.ecview.api.IECViewContainer;
import org.eclipse.osbp.vaaclipse.publicapi.theme.ThemeEngine;
import org.eclipse.osbp.vaaclipse.publicapi.theme.ThemeManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.ui.UI;

@SuppressWarnings("restriction")
public class OSBPServiceAddon implements IPersistenceException.Receiver, IMessageRequester.ClickRecipient {
	private static final Logger log = LoggerFactory.getLogger(OSBPServiceAddon.class);

	@Inject
	private MApplication appModel;

	@Inject
	private IApplicationContext appContext;

	@Inject
	private ThemeEngine themeEngine;

	@Inject
	private ThemeManager themeManager;

	private IDSLMetadataService dslMetadataService;
	
	@Inject
	@Optional
	private IDashboardProvider dashboardProvider;

	protected Map<String, MessageDialog> messageDialogs = new HashMap<>();
	protected Locale addonLocale;


	@PostConstruct
	void init(IEclipseContext context) {
		initApplicationLayoutModel();

		BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext();
		IPersistenceService persistenceService = addToContexts(context, bundleContext, IPersistenceService.class,
				PersistenceService.class, false);
		if (persistenceService != null) {
			persistenceService.registerPersistenceExceptionNotification(this);
		}

//		IEventDispatcher clientDispatcher = ContextInjectionFactory.make(EventDispatcher.class, context);
//		context.set(IEventDispatcher.class, clientDispatcher);
		addToContexts(context, bundleContext, IEventDispatcher.class, EventDispatcher.class, false);

		addToContexts(context, bundleContext, ICommonUIHelper.class, CommonUIHelper.class, false);
		IThemeResourceService themeResourceService = addToContexts(context, bundleContext, IThemeResourceService.class, ThemeResourceService.class, false);
		if(themeResourceService != null) {
			themeResourceService.init(appContext, themeEngine, themeManager);
		}
		addToContexts(context, bundleContext, IReportProvider.class, ReportProvider.class, false);
		IPerspectiveProvider perspectiveProvider = addToContexts(context, null, IPerspectiveProvider.class,
				PerspectiveProvider.class, false);
		dslMetadataService = addToContexts(context, bundleContext, IDSLMetadataService.class, DSLMetadataService.class,
				false);
		addToContexts(context, bundleContext, TranslationService.class, OSBPTranslationService.class, true);
		addToContexts(context, bundleContext, II18nService.class, OSBPI18nService.class, true);
		if (context.get(IDataInterchange.class) == null) {
			log.debug("datainterchange service not present");
		} else {
			log.debug("datainterchange service is in context");
		}

		context.runAndTrack(new RunAndTrack() {
			@Override
			public boolean changed(IEclipseContext context) {
				Locale locale = (Locale) context.get(TranslationService.LOCALE);

				UI ui = context.get(UI.class);
				ui.setLocale(locale);

				OSBPServiceAddon.this.addonLocale = locale;

				// update all ECViews
				IECViewContainer container = context.get(IECViewContainer.class);
				for (IViewEditpart ep : container.getECViews()) {
					ep.getContext().setLocale(locale);
				}

				return true;
			}
		});

		if (perspectiveProvider != null) {
			perspectiveProvider.openPerspective(IPerspectiveProvider.WELCOME_SCREEN_ID, "Welcome", WelcomeView.class);
		}
	}

	/**
	 * Inits the application layout model.
	 *
	 * @param context
	 *            the context
	 */
	private void initApplicationLayoutModel() {
		log.debug("appModel loaded");

		MBindingContext bindingContext = CommandsFactoryImpl.eINSTANCE.createBindingContext();
		bindingContext.setElementId("org.eclipse.osbp.vaaclipse.addons.contexts.dialogAndWindow");
		appModel.getBindingContexts().add(bindingContext);

		MBindingTable bindingTable = CommandsFactoryImpl.eINSTANCE.createBindingTable();
		bindingTable.setElementId(UUID.randomUUID().toString());
		bindingTable.setBindingContext(bindingContext);
		appModel.getBindingTables().add(bindingTable);

		// a trimmed window must come with the application
		MTrimmedWindow trimmedWindow = (MTrimmedWindow) appModel.getChildren().get(0);
		trimmedWindow.setLabel(appContext.getBrandingName());

		for (ICommandsProvider commandsProvider : OSBPCommandsBinder.getCommandsProviders()) {
			commandsProvider.init(appModel);
		}

		// create perspective stack
		if (trimmedWindow.getChildren().isEmpty()) {
			// create perspective stack
			MPerspectiveStack perspectiveStack = AdvancedFactoryImpl.eINSTANCE.createPerspectiveStack();
			perspectiveStack.setElementId(IPerspectiveProvider.E4Constants.PERSPECTIVESTACK);
			perspectiveStack.setToBeRendered(true);
			perspectiveStack.setVisible(true);
			trimmedWindow.getChildren().add(perspectiveStack);
		}

		// create trimbar
		MTrimBar trimBar = BasicFactoryImpl.eINSTANCE.createTrimBar();
		trimBar.setElementId(IPerspectiveProvider.E4Constants.TRIMBAR);
		trimBar.setToBeRendered(true);
		trimBar.setVisible(true);
		trimBar.setSide(SideValue.TOP);
		trimBar.setContainerData("TOPBAR_LEFT");
		trimmedWindow.getTrimBars().add(trimBar);

		MTrimBar trimBar2 = BasicFactoryImpl.eINSTANCE.createTrimBar();
		trimBar2.setElementId(IPerspectiveProvider.E4Constants.TRIMBAR);
		trimBar2.setToBeRendered(true);
		trimBar2.setVisible(true);
		trimBar2.setSide(SideValue.TOP);
		trimBar2.setContainerData("TOPBAR_RIGHT");
		trimmedWindow.getTrimBars().add(trimBar2);

		// add our standard toolcontrols
		if (ProductConfiguration.hasDemoToolsLanguage()) {
			trimBar2.getChildren().add(createToolControl(I18NHandler.class));
		}
		if (ProductConfiguration.hasDemoToolsTheme()) {
			trimBar2.getChildren().add(createToolControl(ThemeHandler.class));
		}
		if (ProductConfiguration.hasToolsPrintService()) {
			trimBar2.getChildren().add(createToolControl(PrintServiceHandler.class));
		}
		trimBar.getChildren().add(createToolControl(UserHandler.class));
		log.debug("toolcontrols added");
	}

	@SuppressWarnings("unchecked")
	private <T, U> T addToContexts(IEclipseContext context, BundleContext bundleContext, Class<T> interfaceClass,
			Class<U> implementationClass, boolean replace) {
		if (context.get(interfaceClass) != null) {
			if (replace) {
				context.remove(interfaceClass);
			} else {
				if (bundleContext != null && bundleContext.getServiceReference(interfaceClass) == null) {
					bundleContext.registerService(interfaceClass, context.get(interfaceClass), null);
				}
				return context.get(interfaceClass);
			}
		}
		try {
			T clazz = (T) ContextInjectionFactory.make(implementationClass, context);
			context.set(interfaceClass, clazz);
			if (bundleContext != null && bundleContext.getServiceReference(interfaceClass) == null) {
				bundleContext.registerService(interfaceClass, clazz, null);
			}
			return clazz;
		} catch (Exception e) {
			log.error("{}", e);
		}
		return null;
	}

	@PreDestroy
	void preDestroy() {
		log.debug("preDestroy");
	}

	private MToolControl createToolControl(Class<?> clzz) {
		MToolControl toolControl = MenuFactoryImpl.eINSTANCE.createToolControl();
		toolControl.setElementId(IPerspectiveProvider.E4Constants.TOOLBARCONTROLITEM_PREFIX + clzz.getSimpleName());
		toolControl.setContributionURI(getClassURI(clzz.getCanonicalName()));
		toolControl.getTags().add(clzz.getSimpleName());
		// avoid persisting
		toolControl.getTags().add("vaaclipse-transient");
		toolControl.setVisible(true);
		toolControl.setToBeRendered(true);
		return toolControl;
	}

	private String getClassURI(String className) {
		String symbolicURI = "bundleclass://"
				+ FrameworkUtil.getBundle(this.getClass()).getHeaders().get("Bundle-SymbolicName").split(";")[0];
		return symbolicURI + "/" + className;
	}

	public String getTranslation(String token) {
		return dslMetadataService.translate(addonLocale.toLanguageTag(), token);
	}

	@Override
	public void exceptionEvent(PersistenceExceptionEvent event) {
		MessageDialog messageDialog = new MessageDialog(UUID.randomUUID().toString(), event.getMessage());
		if (event.isOkButton()) {
			messageDialog.addButton(getTranslation("ok"),
					new MessageEvent(EventType.MESSAGECLOSE, messageDialog.getId()));
			messageDialog.addButtonListener(this);
		}
		messageDialogs.put(messageDialog.getId(), messageDialog);
		UI current=UI.getCurrent();
		if ( current != null ) {
			current.addWindow(messageDialog);
		} else {
			log.error("exceptionEvent is unable to present the message '{}' due to missing current window information!",event.getMessage());
		}
	}

	@Override
	public void messageButtonPressed(MessageRequesterEvent e) {
		MessageDialog messageDialog = messageDialogs.get(e.getId());
		messageDialog.close();
		UI.getCurrent().removeWindow(messageDialog);
		messageDialogs.remove(e.getId());
	}
}
