/*
 * 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
 *    Yatta Solutions - [466264] Enhance UX in simple installer
 */
package org.eclipse.oomph.setup.internal.installer;

import org.eclipse.oomph.jreinfo.JREManager;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.ProfileTransaction.Resolution;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.ui.AbstractSetupDialog;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.Installer;
import org.eclipse.oomph.ui.ErrorDialog;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.OomphPlugin.Preference;
import org.eclipse.oomph.util.PropertiesUtil;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.UIServices;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Eike Stepper
 */
public class InstallerApplication implements IApplication
{
  public static final Integer EXIT_ERROR = 1;

  private static final Preference PREF_MODE = SetupInstallerPlugin.INSTANCE.getConfigurationPreference("mode");

  private static final boolean SKIP_COCOA_MENU = PropertiesUtil.isProperty("oomph.cocoa.menu.skip");

  private Mode mode = Mode.SIMPLE;

  private Integer run(final IApplicationContext context) throws Exception
  {
    // This must come very early, before the first model is accessed, so that HTTPS can be authorized.
    P2Util.getCurrentProvisioningAgent().registerService(UIServices.SERVICE_NAME, SetupWizard.Installer.SERVICE_UI);

    @SuppressWarnings("restriction")
    IProvisioningAgent agent = (IProvisioningAgent)org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper
        .getService(org.eclipse.equinox.internal.p2.repository.Activator.getContext(), IProvisioningAgent.SERVICE_NAME);
    agent.registerService(UIServices.SERVICE_NAME, SetupWizard.Installer.SERVICE_UI);

    final InstallerUI[] installerDialog = { null };

    Thread jreInitializer = new Thread("JRE Initializer")
    {
      @Override
      public void run()
      {
        JREManager.INSTANCE.getJREs();

        for (;;)
        {
          InstallerUI installerUI = installerDialog[0];
          if (installerUI != null)
          {
            installerUI.refreshJREs();
            break;
          }

          try
          {
            sleep(100);
          }
          catch (InterruptedException ex)
          {
            return;
          }
        }
      }
    };

    jreInitializer.setDaemon(true);
    jreInitializer.start();

    int[] sizes = { 16, 32, 48, 64, 128, 256 };
    Image[] images = new Image[sizes.length];
    for (int i = 0; i < sizes.length; i++)
    {
      int size = sizes[i];
      images[i] = SetupInstallerPlugin.INSTANCE.getSWTImage("oomph" + size + ".png");
    }

    Window.setDefaultImages(images);

    boolean restarted = false;
    File restarting = new File(SetupContext.CONFIGURATION_STATE_LOCATION_URI.appendSegment("restarting").toFileString());

    try
    {
      if (restarting.exists())
      {
        restarted = true;
        if (!restarting.delete())
        {
          restarting.deleteOnExit();
        }
      }
    }
    catch (Throwable ex)
    {
      //$FALL-THROUGH$
    }

    final Display display = Display.getDefault();
    Display.setAppName(AbstractSetupDialog.SHELL_TEXT);

    if (!SKIP_COCOA_MENU && Platform.WS_COCOA.equals(Platform.getWS()))
    {
      Runnable about = new Runnable()
      {
        public void run()
        {
          if (installerDialog[0] != null)
          {
            installerDialog[0].showAbout();
          }
        }
      };

      Runnable preferences = new Runnable()
      {
        public void run()
        {
          if (installerDialog[0] != null)
          {
            NetworkConnectionsDialog proxyPreferenceDialog = new NetworkConnectionsDialog(installerDialog[0].getShell());
            proxyPreferenceDialog.open();
          }
        }
      };

      Runnable quit = new Runnable()
      {
        public void run()
        {
          if (installerDialog[0] != null)
          {
            display.dispose();
          }
        }
      };

      CocoaUtil.register(display, about, preferences, quit);
    }

    display.asyncExec(new Runnable()
    {
      public void run()
      {
        // End the splash screen once the dialog is up.
        context.applicationRunning();
      }
    });

    String modeName = PREF_MODE.get(Mode.SIMPLE.name());
    mode = Mode.valueOf(modeName);

    for (;;)
    {
      Installer installer = new Installer();

      if (mode == Mode.ADVANCED)
      {
        if (KeepInstallerUtil.canKeepInstaller())
        {
          Shell shell = new Shell(display);
          if (MessageDialog.openQuestion(shell, AbstractSetupDialog.SHELL_TEXT,
              "As an advanced user, do you want to keep the installer in a permanent location?"))
          {
            if (new KeepInstallerDialog(shell, true).open() == KeepInstallerDialog.OK)
            {
              return EXIT_OK;
            }
          }
        }

        installerDialog[0] = new InstallerDialog(null, installer, restarted);
      }
      else
      {
        SimpleInstallerDialog dialog = new SimpleInstallerDialog(display, installer);
        installer.setSimpleShell(dialog);
        installerDialog[0] = dialog;
      }

      final int retcode = installerDialog[0].show();
      if (retcode == InstallerUI.RETURN_SIMPLE)
      {
        setMode(Mode.SIMPLE);
        continue;
      }

      if (retcode == InstallerUI.RETURN_ADVANCED)
      {
        setMode(Mode.ADVANCED);
        continue;
      }

      if (retcode == InstallerUI.RETURN_RESTART)
      {
        try
        {
          restarting.createNewFile();
        }
        catch (Throwable ex)
        {
          //$FALL-THROUGH$
        }

        String launcher = getLauncher();
        if (launcher != null)
        {
          try
          {
            // EXIT_RESTART often makes the new process come up behind other windows, so try a fresh native process first.
            Runtime.getRuntime().exec(launcher);
            return EXIT_OK;
          }
          catch (Throwable ex)
          {
            //$FALL-THROUGH$
          }
        }

        return EXIT_RESTART;
      }

      return EXIT_OK;
    }
  }

  private void setMode(Mode mode)
  {
    this.mode = mode;
    PREF_MODE.set(mode.name());
  }

  public Object start(IApplicationContext context) throws Exception
  {
    try
    {
      return run(context);
    }
    catch (Throwable t)
    {
      SetupInstallerPlugin.INSTANCE.log(t);
      final AtomicInteger exitCode = new AtomicInteger(EXIT_ERROR);

      ErrorDialog dialog = new ErrorDialog("Error", t, 0, 2, IDialogConstants.OK_LABEL, "Update", IDialogConstants.SHOW_DETAILS_LABEL)
      {
        @Override
        protected void buttonPressed(int buttonId)
        {
          super.buttonPressed(buttonId);

          if (buttonId == 1)
          {
            update();
          }
        }

        private void update()
        {
          try
          {
            final Shell shell = getShell();

            if (!MessageDialog.openQuestion(shell, "Emergency Update", "This is an emergency update. Continue?\n\n"
                + "To lower the risk of problems during this update it will be implied that you accept new licenses or unsigned content."))
            {
              return;
            }

            ProgressMonitorDialog dialog = new ProgressMonitorDialog(shell)
            {
              @Override
              protected Point getInitialSize()
              {
                Point calculatedSize = super.getInitialSize();
                if (calculatedSize.x < 800)
                {
                  calculatedSize.x = 800;
                }

                return calculatedSize;
              }
            };

            try
            {
              dialog.run(true, true, new IRunnableWithProgress()
              {
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
                {
                  SubMonitor progress = SubMonitor.convert(monitor, 2);

                  try
                  {
                    Resolution resolution = SelfUpdate.resolve(null, progress.newChild(1));
                    if (resolution == null)
                    {
                      UIUtil.syncExec(new Runnable()
                      {
                        public void run()
                        {
                          MessageDialog.openInformation(shell, "Update", "No updates were found.");
                        }
                      });

                      return;
                    }

                    resolution.commit(progress.newChild(1));
                    exitCode.set(EXIT_RESTART);
                  }
                  catch (Throwable ex)
                  {
                    throw new InvocationTargetException(ex);
                  }
                  finally
                  {
                    progress.done();
                  }
                }
              });
            }
            catch (OperationCanceledException ex)
            {
              //$FALL-THROUGH$
            }
            catch (InvocationTargetException ex)
            {
              if (!(ex.getCause() instanceof OperationCanceledException))
              {
                throw ex;
              }
            }
          }
          catch (Throwable ex)
          {
            SetupInstallerPlugin.INSTANCE.log(ex);
            ErrorDialog.open(ex);
          }
        }
      };

      dialog.open();

      return exitCode.get();
    }
  }

  public void stop()
  {
    // Do nothing.
  }

  public static String getLauncher()
  {
    try
    {
      String launcher = PropertiesUtil.getProperty("eclipse.launcher");
      if (launcher != null && new File(launcher).isFile())
      {
        return launcher;
      }
    }
    catch (Throwable ex)
    {
      ex.printStackTrace();
      //$FALL-THROUGH$
    }

    return null;
  }

  /**
   * @author Eike Stepper
   */
  public static enum Mode
  {
    SIMPLE, ADVANCED;
  }
}
