/*
 * Copyright (c) 2022 Eike Stepper (Loehne, 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.emf.cdo.lm.ui.views;

import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.etypes.Annotation;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.repositories.CDORepository;
import org.eclipse.emf.cdo.lm.Baseline;
import org.eclipse.emf.cdo.lm.Dependency;
import org.eclipse.emf.cdo.lm.FixedBaseline;
import org.eclipse.emf.cdo.lm.LMPackage;
import org.eclipse.emf.cdo.lm.assembly.AssemblyModule;
import org.eclipse.emf.cdo.lm.assembly.provider.AssemblyEditPlugin;
import org.eclipse.emf.cdo.lm.client.IAssemblyDescriptor;
import org.eclipse.emf.cdo.lm.client.IAssemblyDescriptor.AvailableUpdatesChangedEvent;
import org.eclipse.emf.cdo.lm.client.IAssemblyDescriptor.UpdateStateChangedEvent;
import org.eclipse.emf.cdo.lm.client.IAssemblyDescriptor.Updates;
import org.eclipse.emf.cdo.lm.client.IAssemblyManager;
import org.eclipse.emf.cdo.lm.client.ISystemDescriptor;
import org.eclipse.emf.cdo.lm.internal.client.AssemblyManager;
import org.eclipse.emf.cdo.lm.internal.client.LMManager;
import org.eclipse.emf.cdo.lm.modules.DependencyDefinition;
import org.eclipse.emf.cdo.lm.modules.ModulesFactory;
import org.eclipse.emf.cdo.lm.modules.provider.ModulesEditPlugin;
import org.eclipse.emf.cdo.lm.ui.actions.CheckoutAction;
import org.eclipse.emf.cdo.lm.ui.bundle.OM;
import org.eclipse.emf.cdo.lm.ui.decorators.AvailableUpdatesDecorator;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.ui.compare.CDOCompareEditorUtil;

import org.eclipse.net4j.util.container.IContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.ui.MenuFiller;
import org.eclipse.net4j.util.ui.UIUtil;
import org.eclipse.net4j.util.ui.actions.LongRunningAction;
import org.eclipse.net4j.util.ui.views.ContainerItemProvider;
import org.eclipse.net4j.util.ui.views.ContainerItemProvider.Node;
import org.eclipse.net4j.util.ui.views.ContainerView;
import org.eclipse.net4j.util.ui.views.IElementFilter;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchPage;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

/**
 * @author Eike Stepper
 */
public class AssembliesView extends ContainerView
{
  public static final String ID = "org.eclipse.emf.cdo.lm.AssembliesView";

  public static final String SHOW_IN_MENU_ID = ID + ".ShowInMenu";

  private final InstallUpdatesAction installUpdatesAction = new InstallUpdatesAction();

  private Font bold;

  public AssembliesView()
  {
  }

  @Override
  protected IAssemblyManager getContainer()
  {
    return IAssemblyManager.INSTANCE;
  }

  @Override
  protected void initViewer()
  {
    bold = UIUtil.getBoldFont(getViewer().getControl());
    super.initViewer();
  }

  @Override
  public void dispose()
  {
    UIUtil.dispose(bold);
    super.dispose();
  }

  @Override
  protected ContainerItemProvider<IContainer<Object>> createContainerItemProvider()
  {
    IElementFilter rootElementFilter = getRootElementFilter();
    return new ContainerViewItemProvider(rootElementFilter)
    {
      @Override
      protected Object[] getContainerChildren(ContainerItemProvider<IContainer<Object>>.AbstractContainerNode containerNode, IContainer<?> container)
      {
        Object[] children = super.getContainerChildren(containerNode, container);
        children = addNewModules(container, children);
        return children;
      }

      @Override
      protected Node createNode(Node parent, Object element)
      {
        EList<DependencyDefinition> dependencies = getDependencies(parent, element);
        if (dependencies != null)
        {
          return new FixedChildrenNode(parent, element, dependencies);
        }

        return super.createNode(parent, element);
      }
    };
  }

  @Override
  protected void fillLocalToolBar(IToolBarManager manager)
  {
    manager.add(installUpdatesAction);
    super.fillLocalToolBar(manager);
  }

  @Override
  @SuppressWarnings("restriction")
  protected void fillContextMenu(IMenuManager manager, ITreeSelection selection)
  {
    if (selection == null || selection.size() != 1)
    {
      return;
    }

    Object selectedElement = selection.getFirstElement();
    if (selectedElement == null)
    {
      return;
    }

    IWorkbenchPage page = getSite().getPage();
    TreeViewer viewer = getViewer();

    MenuManager showInMenu = new MenuManager("Show In", SHOW_IN_MENU_ID);
    boolean[] showInFilled = { false };

    if (selectedElement instanceof AssemblyModule)
    {
      AssemblyModule module = (AssemblyModule)selectedElement;

      IAssemblyDescriptor descriptor = IAssemblyManager.INSTANCE.getDescriptor(module);
      if (descriptor != null)
      {
        List<CDOCheckout> checkouts = new ArrayList<>();

        Baseline moduleBaseline = addCheckoutActions(manager, descriptor, module);
        if (moduleBaseline != null)
        {
          IAssemblyManager.INSTANCE.forEachDescriptor(d -> {
            if (d.getBaseline() == moduleBaseline)
            {
              checkouts.add(d.getCheckout());
            }
          });
        }

        String moduleSystemName = module.getAssembly().getSystemName();
        for (CDOCheckout checkout : CDOExplorerUtil.getCheckoutManager().getCheckouts())
        {
          if (!checkout.isOpen())
          {
            Properties properties = LMManager.loadProperties(checkout);
            if (properties != null)
            {
              String systemName = properties.getProperty(AssemblyManager.PROP_SYSTEM_NAME);
              if (Objects.equals(systemName, moduleSystemName))
              {
                CDOID baselineID = CDOIDUtil.read(properties.getProperty(AssemblyManager.PROP_BASELINE_ID));
                if (Objects.equals(baselineID, moduleBaseline.cdoID()))
                {
                  checkouts.add(checkout);
                }
              }
            }
          }
        }

        if (!checkouts.isEmpty())
        {
          showInMenu.add(new org.eclipse.emf.cdo.explorer.ui.checkouts.actions.ShowInActionProvider.ShowInProjectExplorerAction(page,
              checkouts.toArray(new CDOCheckout[checkouts.size()])));
          showInFilled[0] |= true;
        }
      }
    }
    else if (selectedElement instanceof IAssemblyDescriptor)
    {
      IAssemblyDescriptor descriptor = (IAssemblyDescriptor)selectedElement;
      showInMenu.add(new org.eclipse.emf.cdo.explorer.ui.checkouts.actions.ShowInActionProvider.ShowInProjectExplorerAction(page,
          new CDOCheckout[] { descriptor.getCheckout() }));
      showInMenu.add(new org.eclipse.emf.cdo.explorer.ui.checkouts.actions.ShowInActionProvider.ShowInSystemExplorerAction(
          descriptor.getCheckout().getStateFolder(LMManager.STATE_FOLDER_NAME)));
      showInFilled[0] |= true;
    }

    addMenuGroup(manager, "show-in");
    IPluginContainer.INSTANCE.forEachElement(MenuFiller.Factory.PRODUCT_GROUP, MenuFiller.class,
        filler -> showInFilled[0] |= filler.fillMenu(page, viewer, showInMenu, selectedElement));

    if (showInFilled[0])
    {
      manager.add(showInMenu);
    }

    addMenuGroupAdditions(manager);
    IPluginContainer.INSTANCE.forEachElement(MenuFiller.Factory.PRODUCT_GROUP, MenuFiller.class,
        filler -> showInFilled[0] |= filler.fillMenu(page, viewer, manager, selectedElement));

    addMenuGroup(manager, "errors");
    super.fillContextMenu(manager, selection);
  }

  private Baseline addCheckoutActions(IMenuManager manager, IAssemblyDescriptor descriptor, AssemblyModule module)
  {
    Updates updates = descriptor.getAvailableUpdates();
    if (updates != null)
    {
      String moduleName = module.getName();
      AssemblyModule incomingModule = updates.getModifications().get(moduleName);
      if (incomingModule != null)
      {
        Baseline baseline = addCheckoutAction(manager, descriptor, module);
        addCheckoutAction(manager, descriptor, incomingModule);

        manager.add(new Action("Preview Incoming Changes...", ImageDescriptor.createFromImage(CDOCompareEditorUtil.compareImage()))
        {
          @Override
          public void run()
          {
            ISystemDescriptor systemDescriptor = descriptor.getSystemDescriptor();
            CDORepository moduleRepository = systemDescriptor.getModuleRepository(moduleName);
            CDOSession session = moduleRepository.acquireSession();

            try
            {
              CDOBranchManager branchManager = session.getBranchManager();
              CDOBranchPoint leftPoint = module.getBranchPoint().resolve(branchManager);
              CDOBranchPoint rightPoint = incomingModule.getBranchPoint().resolve(branchManager);
              CDOCompareEditorUtil.openDialog(session, leftPoint, rightPoint);
            }
            finally
            {
              moduleRepository.releaseSession();
            }
          }
        });

        return baseline;
      }

      AssemblyModule newModule = updates.getAdditions().get(moduleName);
      if (newModule != null)
      {
        addCheckoutAction(manager, descriptor, newModule);
        return descriptor.getBaseline(module);
      }
    }

    if (!module.isRoot())
    {
      return addCheckoutAction(manager, descriptor, module);
    }

    return descriptor.getBaseline(module);
  }

  private Baseline addCheckoutAction(IMenuManager manager, IAssemblyDescriptor descriptor, AssemblyModule module)
  {
    Baseline baseline = descriptor.getBaseline(module);
    if (baseline != null)
    {
      manager.add(new CheckoutAction(getSite().getPage(), baseline));
    }

    return baseline;
  }

  @Override
  protected void doubleClicked(Object object)
  {
    super.doubleClicked(object);

    if (object instanceof DependencyDefinition)
    {
      DependencyDefinition definition = (DependencyDefinition)object;

      ContainerItemProvider<IContainer<Object>> itemProvider = getItemProvider();
      AssemblyModule module = (AssemblyModule)itemProvider.getParent(definition);
      IAssemblyDescriptor descriptor = (IAssemblyDescriptor)itemProvider.getParent(module);

      AssemblyModule target = descriptor.getModule(definition.getTargetName());
      if (target != null)
      {
        selectReveal(new StructuredSelection(target));
      }
    }
  }

  @Override
  protected void selectionChanged(IActionBars bars, ITreeSelection selection)
  {
    installUpdatesAction.selectionChanged(selection);
  }

  @Override
  protected void handleElementEvent(IEvent event)
  {
    if (event instanceof UpdateStateChangedEvent)
    {
      UIUtil.asyncExec(() -> installUpdatesAction.selectionChanged(getSelection()));
    }
    else if (event instanceof AvailableUpdatesChangedEvent)
    {
      UIUtil.asyncExec(() -> refreshPressed());
    }
  }

  @Override
  protected ViewerComparator createViewerComparator()
  {
    return new ViewerComparator()
    {
      @Override
      public void sort(Viewer viewer, Object[] elements)
      {
        if (elements != null && elements.length != 0 && elements[0] instanceof AssemblyModule)
        {
          // Don't sort dependencies.
          return;
        }

        super.sort(viewer, elements);
      }
    };
  }

  @Override
  protected String getElementText(Object element)
  {
    String text = getText(element);
    if (text != null)
    {
      return text;
    }

    return super.getElementText(element);
  }

  @Override
  protected Image getElementImage(Object element)
  {
    Image image = getImage(element);
    if (image != null)
    {
      return image;
    }

    return super.getElementImage(element);
  }

  @Override
  protected Font getElementFont(Object element)
  {
    Font font = getFont(element, bold, getItemProvider());
    if (font != null)
    {
      return font;
    }

    return super.getElementFont(element);
  }

  @Override
  protected Color getElementForeground(Object element)
  {
    Color foreground = getForeground(element, getDisplay());
    if (foreground != null)
    {
      return foreground;
    }

    return super.getElementForeground(element);
  }

  private static boolean isModuleAddition(Object element)
  {
    if (element instanceof AssemblyModule)
    {
      AssemblyModule module = (AssemblyModule)element;

      IAssemblyDescriptor descriptor = IAssemblyManager.INSTANCE.getDescriptor(module);
      if (descriptor != null)
      {
        if (descriptor.getModule(module.getName()) == null)
        {
          // This must be a module addition in the available updates of the descriptor.
          return true;
        }
      }
    }

    return false;
  }

  public static Object[] addNewModules(IContainer<?> container, Object[] children)
  {
    if (container instanceof IAssemblyDescriptor)
    {
      IAssemblyDescriptor descriptor = (IAssemblyDescriptor)container;

      Updates updates = descriptor.getAvailableUpdates();
      if (updates != null)
      {
        Collection<AssemblyModule> newModules = updates.getAdditions().values();
        if (!newModules.isEmpty())
        {
          List<AssemblyModule> list = new ArrayList<>();

          for (Object child : children)
          {
            list.add((AssemblyModule)child);
          }

          for (AssemblyModule newModule : newModules)
          {
            list.add(newModule);
          }

          children = list.toArray(new AssemblyModule[list.size()]);
        }
      }
    }

    return children;
  }

  public static EList<DependencyDefinition> getDependencies(Node parent, Object element)
  {
    if (element instanceof AssemblyModule)
    {
      AssemblyModule module = (AssemblyModule)element;

      IAssemblyDescriptor descriptor = IAssemblyManager.INSTANCE.getDescriptor(module);
      Baseline baseline = descriptor.getBaseline(module);
      if (baseline instanceof FixedBaseline)
      {
        EList<Dependency> dependencies = ((FixedBaseline)baseline).getDependencies();
        EList<DependencyDefinition> definitions = new BasicEList<>(dependencies.size());

        for (Dependency dependency : dependencies)
        {
          DependencyDefinition definition = ModulesFactory.eINSTANCE.createDependencyDefinition(dependency.getTarget().getName(), dependency.getVersionRange());
          definitions.add(definition);
        }

        return definitions;
      }

      Annotation annotation = module.getAnnotation(LMPackage.ANNOTATION_SOURCE);
      if (annotation != null)
      {
        EList<EObject> contents = annotation.getContents();
        EList<DependencyDefinition> definitions = new BasicEList<>(contents.size());

        for (EObject content : contents)
        {
          if (content instanceof DependencyDefinition)
          {
            DependencyDefinition definition = (DependencyDefinition)content;
            definitions.add(definition);
          }
        }

        return definitions;
      }
    }

    return null;
  }

  public static String getText(Object element)
  {
    if (element instanceof IAssemblyDescriptor)
    {
      IAssemblyDescriptor descriptor = (IAssemblyDescriptor)element;
      return descriptor.getName() + " [" + descriptor.getAssembly().getSystemName() + "]";
    }

    if (element instanceof AssemblyModule)
    {
      AssemblyModule module = (AssemblyModule)element;
      return module.getName() + " " + AvailableUpdatesDecorator.getSuffix(module);
    }

    if (element instanceof DependencyDefinition)
    {
      DependencyDefinition dependency = (DependencyDefinition)element;
      VersionRange versionRange = dependency.getVersionRange();

      String text = dependency.getTargetName();
      if (versionRange != null)
      {
        text += " " + versionRange;
      }

      return text;
    }

    return null;
  }

  public static Image getImage(Object element)
  {
    if (element instanceof IAssemblyDescriptor)
    {
      return ExtendedImageRegistry.INSTANCE.getImage( //
          AssemblyEditPlugin.INSTANCE.getImage("full/obj16/Assembly"));
    }

    if (element instanceof AssemblyModule)
    {
      return ExtendedImageRegistry.INSTANCE.getImage( //
          AssemblyEditPlugin.INSTANCE.getImage(isModuleAddition(element) ? "full/obj16/AssemblyModuleDisabled" : "full/obj16/AssemblyModule"));
    }

    if (element instanceof DependencyDefinition)
    {
      return ExtendedImageRegistry.INSTANCE.getImage( //
          ModulesEditPlugin.INSTANCE.getImage("full/obj16/DependencyDefinition"));
    }

    return null;
  }

  public static Font getFont(Object element, Font bold, ContainerItemProvider<IContainer<Object>> itemProvider)
  {
    if (element instanceof AssemblyModule)
    {
      AssemblyModule module = (AssemblyModule)element;

      if (module.isRoot())
      {
        return bold;
      }
    }

    if (element instanceof DependencyDefinition)
    {
      DependencyDefinition definition = (DependencyDefinition)element;

      AssemblyModule module = (AssemblyModule)itemProvider.getParent(definition);
      if (module.isRoot())
      {
        return bold;
      }
    }

    return null;
  }

  public static Color getForeground(Object element, Display display)
  {
    if (isModuleAddition(element))
    {
      return display.getSystemColor(SWT.COLOR_DARK_GRAY);
    }

    return null;
  }

  /**
   * @author Eike Stepper
   */
  private static final class InstallUpdatesAction extends LongRunningAction
  {
    private IAssemblyDescriptor descriptor;

    public InstallUpdatesAction()
    {
      super("Install Updates...", OM.getImageDescriptor("icons/Update.gif"));
      setToolTipText("Install the available updates into the checkout");
      setEnabled(false);
    }

    public void selectionChanged(ISelection selection)
    {
      descriptor = UIUtil.adaptElement(selection, IAssemblyDescriptor.class);

      if (descriptor == null)
      {
        EObject assemblyElement = UIUtil.adaptElement(selection, EObject.class);
        descriptor = IAssemblyManager.INSTANCE.getDescriptor(assemblyElement);
      }

      setEnabled(descriptor != null && descriptor.hasUpdatesAvailable());
    }

    @Override
    protected void doRun(IProgressMonitor progressMonitor) throws Exception
    {
      if (isEnabled())
      {
        descriptor.update();
      }
    }
  }
}
