/*
 * Copyright (c) 2014, 2015 Eike Stepper (Berlin, Germany) and others.
 * 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
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.targlets.internal.ui;

import org.eclipse.oomph.p2.internal.core.P2Index;
import org.eclipse.oomph.targlets.core.ITargletContainer;
import org.eclipse.oomph.targlets.core.ITargletContainerDescriptor;
import org.eclipse.oomph.targlets.core.ITargletContainerDescriptor.UpdateProblem;
import org.eclipse.oomph.targlets.presentation.TargletEditor;
import org.eclipse.oomph.targlets.provider.TargletItemProviderAdapterFactory;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.ReflectUtil;

import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;

import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.pde.core.target.ITargetDefinition;
import org.eclipse.pde.core.target.ITargetLocation;
import org.eclipse.pde.internal.ui.shared.target.StyledBundleLabelProvider;
import org.eclipse.pde.ui.target.ITargetLocationEditor;
import org.eclipse.pde.ui.target.ITargetLocationUpdater;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Eike Stepper
 */
public class TargletContainerUI implements IAdapterFactory, ITargetLocationEditor, ITargetLocationUpdater
{
  private static final Class<?>[] ADAPTERS = { ITreeContentProvider.class, ILabelProvider.class, ITargetLocationEditor.class, ITargetLocationUpdater.class };

  private static final Object[] NO_CHILDREN = new Object[0];

  private final ComposedAdapterFactory adapterFactory;

  private final AdapterFactoryContentProvider contentProvider;

  private final AdapterFactoryLabelProvider labelProvider;

  public TargletContainerUI()
  {
    adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
    adapterFactory.addAdapterFactory(new TargletItemProviderAdapterFactory(true));

    contentProvider = new AdapterFactoryContentProvider(adapterFactory);
    labelProvider = new AdapterFactoryLabelProvider(adapterFactory);
  }

  public Class<?>[] getAdapterList()
  {
    return ADAPTERS;
  }

  @SuppressWarnings("unchecked")
  public <T> T getAdapter(Object object, Class<T> adapterType)
  {
    if (object instanceof ITargletContainer)
    {
      if (adapterType == ITreeContentProvider.class)
      {
        return (T)new ContainerContentProvider();
      }

      if (adapterType == ILabelProvider.class)
      {
        return (T)new ContainerLabelProvider();
      }

      if (adapterType == ITargetLocationEditor.class)
      {
        return (T)this;
      }

      if (adapterType == ITargetLocationUpdater.class)
      {
        return (T)this;
      }
    }

    return null;
  }

  public boolean canEdit(ITargetDefinition target, ITargetLocation targetLocation)
  {
    return targetLocation instanceof ITargletContainer;
  }

  public IWizard getEditWizard(ITargetDefinition target, ITargetLocation targetLocation)
  {
    final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
    final Display display = window.getShell().getDisplay();

    UIUtil.asyncExec(display, new Runnable()
    {
      public void run()
      {
        try
        {
          Shell activeShell = display.getActiveShell();
          Object data = activeShell.getData();
          if (data instanceof WizardDialog)
          {
            WizardDialog wizardDialog = (WizardDialog)data;

            IWizard wizard = ReflectUtil.getValue("wizard", wizardDialog);
            if (wizard != null)
            {
              wizard.performFinish();
              wizardDialog.close();
            }
          }
        }
        catch (Throwable ex)
        {
          TargletsUIPlugin.INSTANCE.log(ex);
        }
      }
    });

    UIUtil.asyncExec(display, new Runnable()
    {
      public void run()
      {
        try
        {
          Shell activeShell = display.getActiveShell();
          Object data = activeShell.getData();
          if (data instanceof PreferenceDialog)
          {
            PreferenceDialog preferenceDialog = (PreferenceDialog)data;
            ReflectUtil.invokeMethod("okPressed", preferenceDialog);
          }
        }
        catch (Throwable ex)
        {
          TargletsUIPlugin.INSTANCE.log(ex);
        }
      }
    });

    IWorkbenchPage page = window.getActivePage();
    TargletEditor.open(page, ((ITargletContainer)targetLocation).getID());

    return null;
  }

  public boolean canUpdate(ITargetDefinition target, ITargetLocation targetLocation)
  {
    return targetLocation instanceof ITargletContainer;
  }

  public IStatus update(ITargetDefinition target, ITargetLocation targetLocation, IProgressMonitor monitor)
  {
    return ((ITargletContainer)targetLocation).updateProfile(monitor);
  }

  /**
   * @author Eike Stepper
   */
  private class ContainerContentProvider implements ITreeContentProvider
  {
    private StatusWrapper missingIUInfo;

    public ContainerContentProvider()
    {
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
    }

    public void dispose()
    {
    }

    public Object[] getElements(Object element)
    {
      return getChildren(element);
    }

    public Object[] getChildren(Object element)
    {
      if (element instanceof ITargletContainer)
      {
        ITargletContainer location = (ITargletContainer)element;
        List<Object> children = new ArrayList<Object>();

        ITargletContainerDescriptor descriptor = location.getDescriptor();
        if (descriptor != null)
        {
          UpdateProblem updateProblem = descriptor.getUpdateProblem();
          if (updateProblem != null)
          {
            IStatus status = updateProblem.toStatus();
            children.add(new StatusWrapper(status));

            if (descriptor.getWorkingDigest() != null)
            {
              children.add(new StatusWrapper("Content is available from the last working profile"));
            }

            try
            {
              if (updateProblem instanceof UpdateProblem.MissingIU)
              {
                if (missingIUInfo == null)
                {
                  UpdateProblem.MissingIU missingIU = (UpdateProblem.MissingIU)updateProblem;

                  VersionRange range = new VersionRange(missingIU.getRange());
                  Set<P2Index.Repository> repositories = new HashSet<P2Index.Repository>();

                  Map<P2Index.Repository, Set<Version>> simpleResult = P2Index.INSTANCE.lookupCapabilities(missingIU.getNamespace(), missingIU.getName());
                  collectRepositories(simpleResult, range, repositories);

                  Map<P2Index.Repository, Set<Version>> composedResult = P2Index.INSTANCE.generateCapabilitiesFromComposedRepositories(simpleResult);
                  collectRepositories(composedResult, range, repositories);

                  if (!repositories.isEmpty())
                  {
                    missingIUInfo = new StatusWrapper("Found " + repositories.size() + " " + "repositories that satisfy " + missingIU.getNamespace() + "/"
                        + missingIU.getName() + " " + missingIU.getRange());
                    for (P2Index.Repository repository : repositories)
                    {
                      missingIUInfo.addChild(new StatusWrapper(
                          repository.getLocation() + "  (" + (repository.isComposed() ? "composed" : "simple") + ": " + repository.getCapabilityCount() + ")"));
                    }
                  }
                }

                children.add(missingIUInfo);
              }
            }
            catch (Exception ex)
            {
              TargletsUIPlugin.INSTANCE.log(ex);
            }
          }
          else
          {
            for (Object targlet : location.getTarglets())
            {
              children.add(new Wrapper(targlet));
            }
          }
        }

        return children.toArray(new Object[children.size()]);
      }

      return NO_CHILDREN;
    }

    public boolean hasChildren(Object element)
    {
      return getChildren(element).length != 0;
    }

    public Object getParent(Object element)
    {
      return null;
    }

    private void collectRepositories(Map<P2Index.Repository, Set<Version>> result, VersionRange range, Set<P2Index.Repository> repositories)
    {
      for (Map.Entry<P2Index.Repository, Set<Version>> entry : result.entrySet())
      {
        for (Version version : entry.getValue())
        {
          if (range.isIncluded(version))
          {
            repositories.add(entry.getKey());
            break;
          }
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static class ContainerLabelProvider extends StyledBundleLabelProvider
  {
    public ContainerLabelProvider()
    {
      super(true, false);
    }

    @Override
    public Image getImage(Object element)
    {
      if (element instanceof ITargletContainer)
      {
        ITargletContainer location = (ITargletContainer)element;
        String key = "targlet_container";

        ITargletContainerDescriptor descriptor = location.getDescriptor();
        if (descriptor != null)
        {
          UpdateProblem updateProblem = descriptor.getUpdateProblem();
          if (updateProblem != null)
          {
            key += "_problem";
          }
        }

        return TargletsUIPlugin.INSTANCE.getSWTImage(key);
      }

      return super.getImage(element);
    }

    @Override
    public String getText(Object element)
    {
      if (element instanceof ITargletContainer)
      {
        return ((ITargletContainer)element).toString();
      }

      return super.getText(element);
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class StatusWrapper implements ITreeContentProvider, ILabelProvider
  {
    private final int severity;

    private final String message;

    private final List<StatusWrapper> children = new ArrayList<StatusWrapper>();

    public StatusWrapper(int severity, String message)
    {
      this.severity = severity;
      this.message = message;
    }

    public StatusWrapper(IStatus delegate)
    {
      this(delegate.getSeverity(), delegate.getMessage());

      for (IStatus child : delegate.getChildren())
      {
        children.add(new StatusWrapper(child));
      }
    }

    public StatusWrapper(String message)
    {
      this(IStatus.INFO, message);
    }

    public void addChild(StatusWrapper child)
    {
      children.add(child);
    }

    public void dispose()
    {
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
    }

    public Object[] getElements(Object inputElement)
    {
      return getChildren(inputElement);
    }

    public Object[] getChildren(Object parentElement)
    {
      return children.toArray();
    }

    public Object getParent(Object element)
    {
      return null;
    }

    public boolean hasChildren(Object element)
    {
      return !children.isEmpty();
    }

    public void addListener(ILabelProviderListener listener)
    {
    }

    public boolean isLabelProperty(Object element, String property)
    {
      return false;
    }

    public void removeListener(ILabelProviderListener listener)
    {
    }

    public Image getImage(Object element)
    {
      return UIUtil.getStatusImage(severity);
    }

    public String getText(Object element)
    {
      return message;
    }

    @Override
    public String toString()
    {
      return message;
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class Wrapper implements ITreeContentProvider, ILabelProvider
  {
    private final Object wrappedObject;

    public Wrapper(Object wrappedObject)
    {
      this.wrappedObject = wrappedObject;
    }

    public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
    {
      contentProvider.inputChanged(viewer, oldInput, newInput);
    }

    public Object[] getElements(Object object)
    {
      return getChildren(wrappedObject);
    }

    public Object[] getChildren(Object object)
    {
      Object[] children = contentProvider.getChildren(wrappedObject);
      for (int i = 0; i < children.length; i++)
      {
        children[i] = new Wrapper(children[i]);
      }

      return children;
    }

    public boolean hasChildren(Object object)
    {
      return contentProvider.hasChildren(wrappedObject);
    }

    public Object getParent(Object object)
    {
      return contentProvider.getParent(wrappedObject);
    }

    public void addListener(ILabelProviderListener listener)
    {
      labelProvider.addListener(listener);
    }

    public void removeListener(ILabelProviderListener listener)
    {
      labelProvider.removeListener(listener);
    }

    public void dispose()
    {
      labelProvider.dispose();
    }

    public boolean isLabelProperty(Object object, String id)
    {
      return labelProvider.isLabelProperty(wrappedObject, id);
    }

    public Image getImage(Object object)
    {
      return labelProvider.getImage(wrappedObject);
    }

    public String getText(Object object)
    {
      return labelProvider.getText(wrappedObject);
    }
  }
}
