/*
 * Copyright (c) 2016 Ed Merks (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Ed Merks - initial API and implementation
 */
package org.eclipse.oomph.setup.ui.wizards;

import org.eclipse.oomph.base.util.BaseUtil;
import org.eclipse.oomph.setup.Configuration;
import org.eclipse.oomph.setup.EclipseIniTask;
import org.eclipse.oomph.setup.Index;
import org.eclipse.oomph.setup.Installation;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.ProductCatalog;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.Project;
import org.eclipse.oomph.setup.ProjectCatalog;
import org.eclipse.oomph.setup.ProjectContainer;
import org.eclipse.oomph.setup.Scope;
import org.eclipse.oomph.setup.SetupFactory;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.SetupTaskContainer;
import org.eclipse.oomph.setup.Stream;
import org.eclipse.oomph.setup.Workspace;
import org.eclipse.oomph.setup.WorkspaceTask;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.util.CatalogManager;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author Ed Merks
 */
public class ConfigurationProcessor
{
  protected final SetupWizard setupWizard;

  protected final Configuration configuration;

  protected final Workspace workspace;

  protected Installation installation;

  private final ScopeStatus status = new ScopeStatus(null, "Problems were encountered processing the configuration");

  public ConfigurationProcessor(SetupWizard setupWizard)
  {
    this.setupWizard = setupWizard;
    configuration = setupWizard.getConfiguration();
    if (configuration == null)
    {
      installation = null;
      workspace = null;
    }
    else
    {
      installation = configuration.getInstallation();
      workspace = configuration.getWorkspace();
    }

    status.add(new ScopeStatus(installation, "Problems were encountered processing the installation"));
    status.add(new ScopeStatus(null, "Problems were encountered processing the workspace"));
  }

  public IStatus getStatus()
  {
    status.computeSeverity();

    int okCount = 0;
    IStatus result = null;
    for (IStatus status : status.getChildren())
    {
      if (status.isOK())
      {
        ++okCount;
      }
      else
      {
        result = status;
      }
    }

    if (okCount == 1)
    {
      return result;
    }

    return status;
  }

  public boolean processInstallation()
  {
    return installation == null ? handleNullInstallation() : handleInstallation();
  }

  protected MultiStatus getStatus(final Scope scope)
  {
    if (scope instanceof Installation)
    {
      return (MultiStatus)status.getChildren()[0];
    }

    MultiStatus containerStatus = (MultiStatus)status.getChildren()[scope instanceof ProductVersion ? 0 : 1];
    for (IStatus status : containerStatus.getChildren())
    {
      ScopeStatus scopeStatus = (ScopeStatus)status;
      if (scopeStatus.getScope() == scope)
      {
        return scopeStatus;
      }
    }

    ScopeStatus scopeStatus = new ScopeStatus(scope);
    containerStatus.add(scopeStatus);
    return scopeStatus;
  }

  public boolean processWorkspace()
  {
    return workspace == null ? handleNullWorkspace() : handleWorkspace();
  }

  protected boolean handleNullInstallation()
  {
    return true;
  }

  protected boolean handleInstallation()
  {
    ProductVersion productVersion = installation.getProductVersion();
    return productVersion == null ? handleNullProductVersion() : handleProductVersion(productVersion);
  }

  protected boolean handleNullProductVersion()
  {
    addStatus(IStatus.ERROR, installation, "No product version is specified");
    return false;
  }

  protected boolean handleProductVersion(ProductVersion productVersion)
  {
    if (productVersion.eIsProxy())
    {
      return handleProxyProductVersion(productVersion);
    }

    Product product = productVersion.getProduct();
    if (product == null)
    {
      return handleNullProduct(productVersion);
    }

    ProductCatalog productCatalog = product.getProductCatalog();
    CatalogManager catalogManager = setupWizard.getCatalogManager();
    if (productCatalog == null)
    {
      boolean added = false;
      CatalogSelector catalogSelector = new CatalogSelector(catalogManager, true);
      for (Scope scope : catalogSelector.getCatalogs())
      {
        if (isUserProductCatalog(scope))
        {
          ProductCatalog userProductCatalog = (ProductCatalog)scope;
          userProductCatalog.getProducts().add(product);
          BaseUtil.saveEObject(userProductCatalog);
          catalogManager.selectCatalog(true, userProductCatalog, true);
          added = true;
          break;
        }
      }

      if (!added)
      {
        return handleNoUserProductCatalog(productVersion);
      }
    }
    else
    {
      Index index = catalogManager.getIndex();
      Index productCatalogIndex = productCatalog.getIndex();
      if (productCatalogIndex == index)
      {
        if (!"self".equals(productCatalog.getName()))
        {
          catalogManager.selectCatalog(true, productCatalog, true);
        }
      }
      else if (!addCatalog(true, productCatalog, productVersion))
      {
        return handleNoRedirectableProductCatalog(productVersion);
      }
    }

    if ("self.empty.product.version".equals(productVersion.getQualifiedName()))
    {
      return applyEmptyProductVersion();
    }

    return applyProductVersion(productVersion);
  }

  protected boolean applyEmptyProductVersion()
  {
    return false;
  }

  protected boolean applyProductVersion(ProductVersion productVersion)
  {
    return false;
  }

  protected void applyInstallation()
  {
    SetupContext setupContext = SetupContext.create(setupWizard.getResourceSet(), null);
    Installation setupInstallation = setupContext.getInstallation();

    applyAttributes(setupInstallation, installation);
    applySetupTasks(setupInstallation, installation);

    setupWizard.addAppliedConfigurationResource(installation.eResource());
  }

  protected void applyAttributes(Scope targetScope, Scope sourceScope)
  {
    String name = sourceScope.getName();
    if (!StringUtil.isEmpty(name))
    {
      targetScope.setName(name);
    }

    String label = sourceScope.getLabel();
    if (!StringUtil.isEmpty(label))
    {
      targetScope.setLabel(label);
    }

    String description = sourceScope.getDescription();
    if (!StringUtil.isEmpty(description))
    {
      targetScope.setDescription(description);
    }

    targetScope.getAnnotations().addAll(sourceScope.getAnnotations());
  }

  protected void applySetupTasks(SetupTaskContainer targetSetupTaskContainer, SetupTaskContainer sourceSetTaskContainer)
  {
    targetSetupTaskContainer.getSetupTasks().addAll(sourceSetTaskContainer.getSetupTasks());
  }

  protected boolean handleNoRedirectableProductCatalog(ProductVersion productVersion)
  {
    return false;
  }

  protected boolean handleNoUserProductCatalog(ProductVersion productVersion)
  {
    addStatus(IStatus.ERROR, productVersion, "Cannot add the product to the user product catalog because the index doesn't contain one");
    return false;
  }

  protected boolean handleProxyProductVersion(ProductVersion productVersion)
  {
    addStatus(IStatus.ERROR, productVersion, "The product version cannot be resolved");
    return false;
  }

  protected boolean handleNullProduct(ProductVersion productVersion)
  {
    addStatus(IStatus.ERROR, productVersion, "The product version is not contained by a product");
    return false;
  }

  protected boolean handleNullWorkspace()
  {
    return true;
  }

  protected boolean handleWorkspace()
  {
    if (setupWizard.isSimple())
    {
      int answer = new MessageDialog(setupWizard.getShell(), "Configuration Handling", null,
          "The configuration contains a workspace that can only be handled by the advanced mode of the installer.", MessageDialog.WARNING,
          installation == null ? //
              new String[] { "Switch to Advanced Mode", "Cancel" } : //
              new String[] { "Switch to Avanced Mode", "Apply only Installation", "Cancel" },
          0).open();
      switch (answer)
      {
        case 0:
        {
          if (configuration != null)
          {
            setupWizard.addAppliedConfigurationResource(configuration.eResource());
          }

          Collection<? extends Resource> configurationResources = setupWizard.getAppliedConfigurationResources();
          handleSwitchToAdvancedMode();
          setupWizard.setConfigurationResources(configurationResources);
          return false;
        }

        case 1:
        {
          if (installation != null)
          {
            return true;
          }

          return false;
        }

        default:
        {
          return false;
        }
      }
    }

    List<Stream> projectStreams = new ArrayList<Stream>();
    for (Stream stream : workspace.getStreams())
    {
      if (stream.eIsProxy())
      {
        addStatus(IStatus.ERROR, stream, "The referenced stream cannot be resolved");
      }
      else
      {
        Project project = stream.getProject();
        if (project == null)
        {
          addStatus(IStatus.ERROR, stream, "The referenced stream is not contained by a project");
        }
        else
        {
          Project rootProject = project;
          ProjectCatalog projectCatalog = null;
          for (ProjectContainer projectContainer = project.getProjectContainer(); projectContainer != null; projectContainer = projectContainer
              .getProjectContainer())
          {
            if (projectContainer instanceof Project)
            {
              rootProject = (Project)projectContainer;
            }
            else if (projectContainer instanceof ProjectCatalog)
            {
              projectCatalog = (ProjectCatalog)projectContainer;
              break;
            }
          }

          if (projectCatalog == null)
          {
            ProjectContainer logicalProjectContainer = rootProject.getLogicalProjectContainer();
            if (logicalProjectContainer == null)
            {
              addStatus(IStatus.ERROR, stream,
                  "The referenced stream's root project is not contained by a project catalog and it doesn't specify a logical project container: "
                      + EcoreUtil.getURI(rootProject));
            }
            else if (logicalProjectContainer.eIsProxy())
            {
              addStatus(IStatus.ERROR, stream,
                  "The referenced stream's root project is not contained by a project catalog and its logical project container cannot be resolved: "
                      + EcoreUtil.getURI(logicalProjectContainer));
            }
            else if (logicalProjectContainer instanceof Project)
            {
              addStatus(IStatus.ERROR, stream,
                  "The referenced stream's root project is not contained by a project catalog and is not contained by its logical project container: "
                      + EcoreUtil.getURI(logicalProjectContainer));
            }
            else
            {
              // Try to add the catalog.
              ProjectCatalog logicalProjectCatalog = (ProjectCatalog)logicalProjectContainer;
              if (handleStream(logicalProjectCatalog, stream))
              {
                // If the project is in that catalog, we're all good.
                if (logicalProjectCatalog.getProjects().contains(rootProject))
                {
                  projectStreams.add(stream);
                }
                // Try to add the root project to the user extension project of the catalog.
                else if (handleUserProject(logicalProjectCatalog, rootProject))
                {
                  projectStreams.add(stream);
                }
                else
                {
                  addStatus(IStatus.ERROR, stream, "Cannot add the stream's root project: " + EcoreUtil.getURI(rootProject));
                  addStatus(IStatus.ERROR, stream,
                      "The target project catalog does not contain an extensible user project: " + EcoreUtil.getURI(logicalProjectCatalog));
                }
              }
              else
              {
                // Errors already handled.
              }
            }
          }
          else
          {
            if (handleStream(projectCatalog, stream))
            {
              projectStreams.add(stream);
            }
            else
            {
              // Errors already handled.
            }
          }
        }
      }
    }

    if (projectStreams.isEmpty() ? applyNoStreams() : applyStreams(projectStreams))
    {
      return applyWorkspace();
    }

    return false;
  }

  protected boolean applyWorkspace()
  {
    SetupContext setupContext = SetupContext.create(installation, Collections.<Stream> emptyList(), null);
    Workspace setupWorkspace = setupContext.getWorkspace();

    applyAttributes(setupWorkspace, workspace);
    applySetupTasks(setupWorkspace, workspace);

    if (setupWorkspace.getStreams().isEmpty() && !setupWorkspace.getSetupTasks().isEmpty())
    {
      WorkspaceTask workspaceTask = SetupFactory.eINSTANCE.createWorkspaceTask();
      workspaceTask.setID("workspace");
      setupWorkspace.getSetupTasks().add(0, workspaceTask);
    }

    setupWizard.addAppliedConfigurationResource(workspace.eResource());

    return true;
  }

  protected boolean applyStreams(List<Stream> streams)
  {
    return true;
  }

  protected boolean applyNoStreams()
  {
    return true;
  }

  protected boolean handleNoRedirectableProjectCatalog(Stream stream)
  {
    return false;
  }

  protected boolean handleUserProject(ProjectCatalog projectCatalog, Project project)
  {
    CatalogManager catalogManager = setupWizard.getCatalogManager();
    for (Project catalogProject : projectCatalog.getProjects())
    {
      if (isUserProject(catalogProject))
      {
        catalogProject.getProjects().add(project);
        BaseUtil.saveEObject(catalogProject);
        catalogManager.selectCatalog(false, projectCatalog, true);
        return true;
      }
    }

    // addStatus(IStatus.ERROR, , message);

    return false;
  }

  protected boolean handleStream(ProjectCatalog projectCatalog, Stream stream)
  {
    CatalogManager catalogManager = setupWizard.getCatalogManager();
    Index projectIndex = projectCatalog.getIndex();
    Index index = catalogManager.getIndex();
    if (projectIndex != index && !addCatalog(false, projectCatalog, stream))
    {
      return handleNoRedirectableProjectCatalog(stream);
    }

    catalogManager.selectCatalog(false, projectCatalog, true);

    return true;
  }

  protected boolean addCatalog(boolean product, Scope catalogScope, Scope originatingScope)
  {
    CatalogManager catalogManager = setupWizard.getCatalogManager();
    Scope catalog = catalogManager.getCatalog(product, "redirectable");
    String label = product ? "product" : "project";
    if (catalog == null)
    {
      addStatus(IStatus.ERROR, originatingScope, "Cannot add the catalog " + EcoreUtil.getURI(catalogScope));

      ResourceSet resourceSet = setupWizard.getResourceSet();
      Resource resource = resourceSet.getResource(URI.createURI("index:/redirectable." + label + "s.setup"), false);
      if (resource == null)
      {
        addStatus(IStatus.ERROR, originatingScope, "There is no redirectable " + label + " catalog is in the index");
      }
      else
      {
        addStatus(IStatus.ERROR, originatingScope,
            "The redirectable " + label + " catalog in the index is already redirected to " + resourceSet.getURIConverter().normalize(resource.getURI()));
      }

      return false;
    }

    Resource catalogResource = catalog.eResource();
    URI sourceURI = catalogResource.getURI();
    URI targetURI = catalogScope.eResource().getURI();
    EcoreUtil.replace(catalog, catalogScope);
    catalogManager.selectCatalog(product, catalogScope, true);
    catalogResource.getResourceSet().getURIConverter().getURIMap().put(targetURI, sourceURI);

    EList<SetupTask> setupTasks = (product ? installation : workspace).getSetupTasks();
    EclipseIniTask redirectionEclipseIniTask = SetupFactory.eINSTANCE.createEclipseIniTask();
    redirectionEclipseIniTask.setVm(true);
    redirectionEclipseIniTask.setOption("-Doomph.redirection." + (product ? "products" : "projects") + "=");
    redirectionEclipseIniTask.setValue(sourceURI + "->" + targetURI);
    setupTasks.add(0, redirectionEclipseIniTask);

    return true;
  }

  protected void addStatus(int severity, Scope scope, String message)
  {
    MultiStatus containerStatus = getStatus(scope);
    containerStatus.add(new Status(severity, SetupUIPlugin.PLUGIN_ID, message));
  }

  protected void handleSwitchToAdvancedMode()
  {
  }

  public static boolean isUserProject(Project project)
  {
    Resource resource = project.eResource();
    return resource != null && SetupContext.isUserScheme(resource.getURI().scheme());
  }

  public static boolean isUserProductCatalog(Scope scope)
  {
    if (scope instanceof ProductCatalog)
    {
      Resource resource = scope.eResource();
      return resource != null && SetupContext.isUserScheme(resource.getURI().scheme());
    }

    return false;
  }

  private static class ScopeStatus extends MultiStatus
  {
    private final Scope scope;

    public ScopeStatus(Scope scope)
    {
      super(SetupUIPlugin.PLUGIN_ID, 0, "Processing " + EcoreUtil.getURI(scope), null);
      this.scope = scope;
    }

    public ScopeStatus(Scope scope, String message)
    {
      super(SetupUIPlugin.PLUGIN_ID, 0, message, null);
      this.scope = scope;
    }

    public Scope getScope()
    {
      return scope;
    }

    public int computeSeverity()
    {
      for (IStatus status : getChildren())
      {
        int newSev = status instanceof ScopeStatus ? ((ScopeStatus)status).computeSeverity() : status.getSeverity();
        if (newSev > getSeverity())
        {
          setSeverity(newSev);
        }
      }

      return getSeverity();
    }
  }
}
