/*
 * Copyright (c) 2014 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.setup.internal.installer;

import org.eclipse.oomph.p2.P2Factory;
import org.eclipse.oomph.p2.ProfileDefinition;
import org.eclipse.oomph.p2.Repository;
import org.eclipse.oomph.p2.Requirement;
import org.eclipse.oomph.p2.core.Agent;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.Profile;
import org.eclipse.oomph.p2.core.ProfileTransaction;
import org.eclipse.oomph.p2.core.ProfileTransaction.CommitContext;
import org.eclipse.oomph.p2.core.ProfileTransaction.Resolution;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.p2.impl.P2TaskImpl;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.setup.ui.UnsignedContentDialog;
import org.eclipse.oomph.setup.ui.wizards.ProgressPage;
import org.eclipse.oomph.ui.ErrorDialog;
import org.eclipse.oomph.ui.UICallback;
import org.eclipse.oomph.util.Confirmer;
import org.eclipse.oomph.util.ExceptionHandler;
import org.eclipse.oomph.util.IRunnable;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.oomph.util.StringUtil;

import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.p2.engine.IProvisioningPlan;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.swt.widgets.Shell;

import java.lang.reflect.InvocationTargetException;

/**
 * @author Eike Stepper
 */
public class SelfUpdate
{
  private static final String PROP_INSTALLER_UPDATE_URL = "oomph.installer.update.url";

  private static final String DEFAULT_INSTALLER_UPDATE_URL = "http://download.eclipse.org/oomph/products/repository";

  public static final String INSTALLER_UPDATE_URL = PropertiesUtil.getProperty(PROP_INSTALLER_UPDATE_URL, DEFAULT_INSTALLER_UPDATE_URL).replace('\\', '/');

  public static Resolution resolve(final User user, IProgressMonitor monitor) throws CoreException
  {
    Agent agent = P2Util.getAgentManager().getCurrentAgent();
    Profile profile = agent.getCurrentProfile();
    ProfileTransaction transaction = profile.change();

    // TODO Remove this temporary range conversion when all users can be expected to have a major range.
    VersionRange deprecatedVersionRange = new VersionRange("[1.0.0,1.1.0)");
    ProfileDefinition profileDefinition = transaction.getProfileDefinition();
    for (Requirement requirement : profileDefinition.getRequirements())
    {
      if (IInstallableUnit.NAMESPACE_IU_ID.equals(requirement.getNamespace()) && SetupUIPlugin.PRODUCT_ID.equals(requirement.getName())
          && deprecatedVersionRange.equals(requirement.getVersionRange()))
      {
        requirement.setVersionRange(new VersionRange("[1.0.0,2.0.0)"));
        transaction.commit(monitor);
        transaction = profile.change();
        break;
      }
    }

    final boolean repositoryChanged = changeRepositoryIfNeeded(transaction);

    CommitContext commitContext = new CommitContext()
    {
      private IProvisioningPlan provisioningPlan;

      @Override
      public boolean handleProvisioningPlan(ResolutionInfo info) throws CoreException
      {
        if (repositoryChanged && info.getIUDeltas().isEmpty() && info.getPropertyDeltas().size() <= 1)
        {
          // Cancel if only the repository addition would be committed.
          return false;
        }

        provisioningPlan = info.getProvisioningPlan();
        return true;
      }

      @Override
      public Confirmer getUnsignedContentConfirmer()
      {
        if (user == null)
        {
          return Confirmer.ACCEPT;
        }

        P2TaskImpl.processLicenses(provisioningPlan, ProgressPage.LICENSE_CONFIRMER, user, true, new NullProgressMonitor());
        provisioningPlan = null;

        return UnsignedContentDialog.createUnsignedContentConfirmer(user, true);
      }
    };

    return transaction.resolve(commitContext, monitor);
  }

  public static void update(Shell shell, final Resolution resolution, final Runnable successRunnable, final ExceptionHandler<CoreException> exceptionHandler,
      final Runnable finalRunnable)
  {
    String shellText = shell.getText();
    if (!StringUtil.isEmpty(shellText))
    {
      shellText += " ";
    }

    final UICallback callback = new UICallback(shell, shellText + "Update");
    callback.runInProgressDialog(false, new IRunnable()
    {
      public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
      {
        try
        {
          resolution.commit(monitor);

          callback.execInUI(true, new Runnable()
          {
            public void run()
            {
              callback.information(false, "Updates were installed. Press OK to restart.");

              if (successRunnable != null)
              {
                successRunnable.run();
              }
            }
          });
        }
        catch (final CoreException ex)
        {
          if (exceptionHandler != null)
          {
            exceptionHandler.handleException(ex);
          }
          else
          {
            ErrorDialog.open(ex);
          }
        }
        finally
        {
          if (finalRunnable != null)
          {
            finalRunnable.run();
          }
        }
      }
    });
  }

  private static boolean changeRepositoryIfNeeded(ProfileTransaction transaction)
  {
    ProfileDefinition profileDefinition = transaction.getProfileDefinition();

    EList<Repository> repositories = profileDefinition.getRepositories();
    if (repositories.size() != 1 || !INSTALLER_UPDATE_URL.equals(repositories.get(0).getURL()))
    {
      Repository repository = P2Factory.eINSTANCE.createRepository(INSTALLER_UPDATE_URL);
      profileDefinition.setRepositories(ECollections.singletonEList(repository));
      return true;
    }

    return false;
  }
}
