/*******************************************************************************
 * Copyright (c) 2017-2019 Cisco Systems, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.tigerstripe.workbench.ui.internal.dialogs;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tigerstripe.workbench.TigerstripeException;
import org.eclipse.tigerstripe.workbench.internal.BasePlugin;
import org.eclipse.tigerstripe.workbench.model.IModelSynchronizationListener;
import org.eclipse.tigerstripe.workbench.project.IModelReference;
import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject;
import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProjectInternal;
import org.eclipse.tigerstripe.workbench.ui.EclipsePlugin;
import org.eclipse.tigerstripe.workbench.ui.internal.editors.descriptor.dependencies.ReferenceDetails;
import org.eclipse.tigerstripe.workbench.ui.internal.preferences.ContributionsPreferencePage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.osgi.framework.Bundle;

public class CustomTigerstripeDependenciesManager implements ICustomTigerstripeDependenciesManager {
    private static String EXT_POINT = "org.eclipse.tigerstripe.workbench.base.customTigerstripeDependencies";
    private static final String ATTR_CLASS = "class";
    private static String DIALOG_CLASS = "dialog_class";
    private static String TRANSITIVE = "transitiveSupported";
    
    private static String LISTENER = "listener";
    private static String DETAILS_PAGE = "details_page";
    private static String LABEL_PROVIDER = "label_provider";

    private IModelSynchronizationListener[] syncListeners;
    private static IConfigurationElement dialogElement;
    private static IConfigurationElement labelProviderElement;
    private static IConfigurationElement detailsPageElement;
    private static boolean transitivesChecked = false;
    private static boolean transitiveValue = true;

    public static boolean hasCustomDialog() {
        IPreferenceStore store = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, BasePlugin.PLUGIN_ID);
        if (store.getBoolean(ContributionsPreferencePage.P_USE_CUSTOM_DEPENDENCIES_DIALOG)) {
            if (dialogElement == null) {
                getRegisteredDependenciesDialog();
            }
            return dialogElement != null;
        }
        return false;
    }

    public static boolean hasCustomLabelProvider() {
        IPreferenceStore store = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, BasePlugin.PLUGIN_ID);
        if (store.getBoolean(ContributionsPreferencePage.P_USE_CUSTOM_DEPENDENCIES_LABELPROVIDER)) {
            if (labelProviderElement == null) {
                getRegisteredDependenciesLabelProvider();
            }
            return labelProviderElement != null;
        }
        return false;
    }
    
    public static boolean hasCustomDetailsPage() {
        IPreferenceStore store = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, BasePlugin.PLUGIN_ID);
        if (store.getBoolean(ContributionsPreferencePage.P_USE_CUSTOM_DEPENDENCIES_DETAILSPAGE)) {
            if (detailsPageElement == null) {
                getRegisteredDependenciesDetailsPage();
            }
            return detailsPageElement != null;
        }
        return false;
    }
    

    public static boolean isTransitiveSupported() {
        IPreferenceStore store = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, BasePlugin.PLUGIN_ID);
        if (store.getBoolean(ContributionsPreferencePage.P_USE_CUSTOM_DEPENDENCIES_DIALOG)) {
            if (! transitivesChecked) {
                IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_POINT); // $NON-NLS-1$
                // set initial value in case there is no config!
                transitiveValue = (config.length == 0);

                for (IConfigurationElement configElement : config) {
                    // The presence of the element means it does
                    if (configElement.getName().equals(TRANSITIVE)) {
                        transitiveValue = true;
                        break;
                    }
                }
                transitivesChecked = true;
            }
        }
        return transitiveValue;    
    }

    public static synchronized IProjectSelectionDialog makeDialog(Shell shell,
            final Set<String> filteredOutProjects, final ITigerstripeModelProject currentProject)
                    throws TigerstripeException {

        // Note this assumes that the check to see if it is provided has been
        // used
        // as that is where we check for a preference
        if (dialogElement == null) {
            getRegisteredDependenciesDialog();
        }

        IConfigurationElement element = dialogElement;
        if (element != null) {
            try {
                Bundle bundle = Platform.getBundle(element.getContributor().getName());
                String className = element.getAttribute(DIALOG_CLASS);
                Class<?> extensionClass = bundle.loadClass(className);

                for (Constructor<?> constructor : extensionClass.getDeclaredConstructors()) {
                    Class<?>[] paramTypes = constructor.getParameterTypes();
                    if (paramTypes.length == 3 && paramTypes[0].isAssignableFrom(Shell.class)) {

                        return (IProjectSelectionDialog) constructor.newInstance(shell, filteredOutProjects,
                                currentProject);
                    }
                }
                return null;
            } catch (Exception e) {
                EclipsePlugin.log(e);
            }
        }
        throw new TigerstripeException("Couldn't instantiate custom dependencies dialog");

    }

    public static ITableLabelProvider makeLabelProvider() {
        if (labelProviderElement == null) {
            getRegisteredDependenciesLabelProvider();
        }
        
        IConfigurationElement element = labelProviderElement;
        if (element != null) {
                Bundle bundle = Platform.getBundle(element.getContributor().getName());
                try {
                    return (ITableLabelProvider) element.createExecutableExtension(ATTR_CLASS);
                } catch (InvalidRegistryObjectException | CoreException e) {
                    EclipsePlugin.log(e);
                }
        }
        return null;
                
    }
    
    public static ReferenceDetails makeReferenceDetailsPage(FormToolkit toolkit, Composite container) 
            throws TigerstripeException {
        if (detailsPageElement == null) {
            getRegisteredDependenciesDetailsPage();;
        }
        
        IConfigurationElement element = detailsPageElement;
        if (element != null) {
            try {
                Bundle bundle = Platform.getBundle(element.getContributor().getName());
                String className = element.getAttribute(ATTR_CLASS);
                Class<?> extensionClass = bundle.loadClass(className);

                for (Constructor<?> constructor : extensionClass.getDeclaredConstructors()) {
                    Class<?>[] paramTypes = constructor.getParameterTypes();
                    if (paramTypes.length == 2 && paramTypes[0].isAssignableFrom(FormToolkit.class) &&
                            paramTypes[1].isAssignableFrom(Composite.class)) {
                        return (ReferenceDetails) constructor.newInstance(toolkit,container);
                    }
                }
                return null;
            } catch (Exception e) {
                EclipsePlugin.log(e);
            }
        }
        throw new TigerstripeException("Couldn't instantiate custom Details Page");
    }
    
    private static void getRegisteredDependenciesDialog() {
        IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_POINT); // $NON-NLS-1$
        for (IConfigurationElement configElement : config) {
            if (configElement.getAttribute(DIALOG_CLASS) != null) {
                dialogElement = configElement;
                break;
            }
        }
    }
    
    private static void getRegisteredDependenciesLabelProvider() {
        IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_POINT); // $NON-NLS-1$
        for (IConfigurationElement configElement : config) {
            if (configElement.getName().equals(LABEL_PROVIDER) && configElement.getAttribute(ATTR_CLASS) != null) {
                labelProviderElement = configElement;
                break;
            }
        }
    }
    
    private static void getRegisteredDependenciesDetailsPage() {
        IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_POINT); // $NON-NLS-1$
        for (IConfigurationElement configElement : config) {
            if (configElement.getName().equals(DETAILS_PAGE) && configElement.getAttribute(ATTR_CLASS) != null) {
                detailsPageElement = configElement;
                break;
            }
        }
    }

    public void fireSaved(final ITigerstripeModelProjectInternal project) {
        for (IModelSynchronizationListener listener : getSyncListeners()) {
            listener.saved(project);
        }
    }

    public void fireDisposed(final ITigerstripeModelProjectInternal project) {
        for (IModelSynchronizationListener listener : getSyncListeners()) {
            listener.disposed(project);
        }
    }

    public void fireRemoveDependencies(final ITigerstripeModelProjectInternal project,
            final Map<String, IModelReference> modelRefMap) {
        for (IModelSynchronizationListener listener : getSyncListeners()) {
            listener.removed(project, modelRefMap);
        }
    }

    private IModelSynchronizationListener[] getSyncListeners() {
        if (syncListeners == null) {
            List<IModelSynchronizationListener> list = new ArrayList<>();
            IConfigurationElement[] configs = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_POINT);
            for (IConfigurationElement configElement : configs) {
                try {
                    if (configElement.getName().equals(LISTENER) && configElement.getAttribute(ATTR_CLASS) != null) {
                        IModelSynchronizationListener listener = (IModelSynchronizationListener) configElement
                                .createExecutableExtension(ATTR_CLASS);
                        list.add(listener);
                    }
                } catch (Exception e) {
                    EclipsePlugin.log(e);
                }
            }
            syncListeners = list.toArray(new IModelSynchronizationListener[list.size()]);
        }
        return syncListeners;
    }


}
