/**
 ********************************************************************************
 * Copyright (c) 2017-2020 Robert Bosch GmbH and others.
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Robert Bosch GmbH - initial API and implementation
 ********************************************************************************
 */
package org.eclipse.app4mc.sca2amalthea.ui.handlers;

import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.app4mc.sca.logging.manager.Logmanager;
import org.eclipse.app4mc.sca2amalthea.llvm.headless.GenerateAmaltheaModelFromLLVM;
import org.eclipse.app4mc.sca2amalthea.ui.Activator;
import org.eclipse.app4mc.sca2amalthea.utils.UtilityForProcessHandling;
import org.eclipse.app4mc.sca2amalthea.utils.constants.SCA2AmaltheaConstants;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.internal.resources.Resource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;


/**
 */
@SuppressWarnings("restriction")
public class SCAToAmaltheaHandler extends AbstractHandler {

  private String cFilePath = "";
  private String traverseASTPath = "";
  private String outPutPath = "";
  private String taskListFile = "";
  private String headerTextFilePath = "";
  private String buildCmdLogFilePath = "";
  private String lockfunctionFile = "";
  private boolean isStructMemberEnabled = false;
  private volatile Boolean isGenerationDone = Boolean.FALSE;
  private final Object mutex = new Object();
  private Job currentJob = null;
  private boolean confirmation = true;
  private Shell currentShell;
  private static String infoMessage;
  private static String confirmationMessage;
  private static String title;
  private static int timerDelay;
  private static int timerPeriod;

  /**
   * Sets the timer delay for the timer
   *
   * @param timerDelay time delay in milliseconds.
   */
  public static void setTimerDelay(final int timerDelay) {
    SCAToAmaltheaHandler.timerDelay = timerDelay;
  }

  /**
   * Returns the timer delay that was set.
   *
   * @return timer delay.
   */
  public static int getTimerDelay() {
    return SCAToAmaltheaHandler.timerDelay;
  }

  /**
   * Sets the time period after which the timer task would be executed.
   *
   * @param timerPeriod time period in milliseonds.
   */
  public static void setTimerPeriod(final int timerPeriod) {
    SCAToAmaltheaHandler.timerPeriod = timerPeriod;
  }

  /**
   * Returns the time period that was set.
   *
   * @return timer period.
   */
  public static int getTimerPeriod() {
    return SCAToAmaltheaHandler.timerPeriod;
  }


  @Override
  public Object execute(final ExecutionEvent event) throws ExecutionException {

    IPreferenceStore preferenceStore = org.eclipse.app4mc.sca2amalthea.utils.Activator.getDefault().getPreferenceStore();
    this.currentShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
    if (event != null) {
      ISelection selection = HandlerUtil.getCurrentSelection(event);
      if (((TreeSelection) selection).getFirstElement() instanceof Resource) {
        Resource resource = (Resource) ((TreeSelection) selection).getFirstElement();
        this.cFilePath = resource.getLocation().toString();
        this.isStructMemberEnabled = preferenceStore.getBoolean(SCA2AmaltheaConstants.ENABLE_STRUCT_MEMBER);
      }
    }

    this.traverseASTPath = preferenceStore.getString(SCA2AmaltheaConstants.AST_PATH);
    this.taskListFile = preferenceStore.getString(SCA2AmaltheaConstants.TASK_INFO);
    this.headerTextFilePath = preferenceStore.getString(SCA2AmaltheaConstants.HDIR_LIST);
    this.buildCmdLogFilePath = preferenceStore.getString(SCA2AmaltheaConstants.BLOG);
    this.lockfunctionFile = preferenceStore.getString(SCA2AmaltheaConstants.LOCK_INFO);
    if (preferenceStore.getBoolean(SCA2AmaltheaConstants.ENABLE_OPTIONAL_FIELDS)) {
      this.outPutPath = preferenceStore.getString(SCA2AmaltheaConstants.OUTPUT_PATH);
    }
    else {
      this.outPutPath = preferenceStore.getDefaultString(SCA2AmaltheaConstants.OUTPUT_PATH);

    }

    if(this.traverseASTPath.isEmpty()){
    	MessageDialog.openError(this.currentShell, "Error Amalthea model generation", "Path to LLVM executable is not configured in sca2Amalthea preferences");
    }
    else{
    if (UtilityForProcessHandling.getCurrentRunningProcess() == null) {
      createAndExecuteJobForModelGeneration();
    }
    else {
      String information = "The generation of 2 models at the same time is not allowed";
      this.currentShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
      MessageDialog.openInformation(this.currentShell, "Operation not allowed", information);
      Logmanager.getInstance().log(information);
    }
    }

    return null;
  }

  /**
   *
   */
  private void createAndExecuteJobForModelGeneration() {
    Job job = new Job("AMALTHEA model generation") {

      @Override
      public IStatus run(final IProgressMonitor monitor) {
        final SubMonitor subMonitor = SubMonitor.convert(monitor, 600);
        Thread progressMonitorObserverThread = null;
        boolean isPopupToBeDisplayed = false;
        try {
          progressMonitorObserverThread = createInfiniteProgressMonitor(subMonitor);
          progressMonitorObserverThread.start();
          GenerateAmaltheaModelFromLLVM generator = new GenerateAmaltheaModelFromLLVM(
              SCAToAmaltheaHandler.this.cFilePath, SCAToAmaltheaHandler.this.outPutPath,
              SCAToAmaltheaHandler.this.traverseASTPath, SCAToAmaltheaHandler.this.taskListFile,
              SCAToAmaltheaHandler.this.headerTextFilePath, SCAToAmaltheaHandler.this.buildCmdLogFilePath,
              SCAToAmaltheaHandler.this.lockfunctionFile,
              SCAToAmaltheaHandler.this.isStructMemberEnabled);
          setInfoMessage("The time required to generate the Amalthea model depends on the size of the PVER.");
          setTitle("Information-Amalthea Model Generation");
          Display.getDefault().syncExec(new InfoPopUp());
          startTimer();
          int returncode = generator.run();
          synchronized (SCAToAmaltheaHandler.this.mutex) {
            SCAToAmaltheaHandler.this.isGenerationDone = true;
          }
          // check the exit status of the process and show a information popup
          if ((returncode != 0) || (UtilityForProcessHandling.getCurrentRunningProcess().exitValue() != 0)) {
            if (SCAToAmaltheaHandler.this.confirmation) {
              setInfoMessage("There was some error while parsing c files or when generating the AMALTHEA model.");
              setTitle("Error");
              Display.getDefault().syncExec(new InfoPopUp());
            }
            else {
              SCAToAmaltheaHandler.this.confirmation = true;
            }
            UtilityForProcessHandling.setCurrentRunningProcess(null);
          }
          else {
            isPopupToBeDisplayed = true;
          }
        }
        catch (Exception e) {
          Logmanager.getInstance().logException(this.getClass(), e, Activator.PLUGIN_ID);

          if (progressMonitorObserverThread != null) {
            waitForThread(progressMonitorObserverThread);
          }

          subMonitor.done();
          return Status.CANCEL_STATUS;
        }
        waitForThread(progressMonitorObserverThread);
        subMonitor.done();
        if (isPopupToBeDisplayed) {
          setInfoMessage("Amathea model generation completed");
          setTitle("Amathea model generated");
          Display.getDefault().syncExec(new InfoPopUp());
        }
        return new Status(IStatus.OK, Activator.PLUGIN_ID, "AMALTHEA model generation completed");
      }


      /**
       * @param t
       */
      private void waitForThread(final Thread t) {
        try {
          if (t != null) {
            t.join();
          }
        }
        catch (InterruptedException e) {
          Logmanager.getInstance().log(e.getMessage());
        }
      }
    };
    this.currentJob = job;
    job.schedule();
  }

  /**
   * @param subMonitor
   */
  private Thread createInfiniteProgressMonitor(final SubMonitor subMonitor) {
    return new InfiniteProgressMonitorObserver(subMonitor);
  }

  class InfiniteProgressMonitorObserver extends Thread {

    private String message = "Terminating AMALTHEA model generation job";
    private final SubMonitor subMonitor;

    /**
     * @param subMonitor monitor which will be observed
     */
    public InfiniteProgressMonitorObserver(final SubMonitor subMonitor) {
      super();
      this.subMonitor = subMonitor;
    }

    @Override
    public void run() {

      this.message = runLogarithmicWaitOnProgressMonitor();

      terminateMonitorIn10Secondes();

      UtilityForProcessHandling.setCurrentRunningProcess(null);
      UtilityForProcessHandling.setModelGenerationcancelled(false);
      SCAToAmaltheaHandler.this.isGenerationDone = false;
    }

    /**
     * @param subMonitor
     * @param message
     * @return
     */
    private String runLogarithmicWaitOnProgressMonitor() {
      String messageToRenameJob = "Terminating AMALTHEA model generation job";
      boolean isProcessCompleted = false;
      int advancementCounter = 0;

      while (!isProcessCompleted) {
        if (this.subMonitor.isCanceled()) {
          synchronized (SCAToAmaltheaHandler.this.mutex) {
            SCAToAmaltheaHandler.this.isGenerationDone = true;
          }
          Process p = UtilityForProcessHandling.getCurrentRunningProcess();
          p.destroyForcibly();

          UtilityForProcessHandling.setCurrentRunningProcess(null);
          UtilityForProcessHandling.setModelGenerationcancelled(true);

          messageToRenameJob = "Cancelling the model generation job";
        }
        try {
          this.subMonitor.worked(1);
          advancementCounter++;
          if ((advancementCounter % 300) == 0) {
            advancementCounter = 1;
            this.subMonitor.setWorkRemaining(600);
          }
          Thread.sleep(1000);
        }
        catch (InterruptedException e) {
          Logmanager.getInstance().log(e.getMessage());
        }
        synchronized (SCAToAmaltheaHandler.this.mutex) {
          isProcessCompleted = SCAToAmaltheaHandler.this.isGenerationDone;
        }
      }
      return messageToRenameJob;
    }

    /**
     * @param subMonitor
     * @param message
     */
    private void terminateMonitorIn10Secondes() {
      int numberOfSecondUntilEnd = 10;
      this.subMonitor.setWorkRemaining(numberOfSecondUntilEnd);
      this.subMonitor.setTaskName(this.message);
      SCAToAmaltheaHandler.this.currentJob.setName(this.message);
      while (numberOfSecondUntilEnd > 0) {
        try {
          this.subMonitor.worked(1);
          Thread.sleep(1000);
        }
        catch (InterruptedException e) {
          Logmanager.getInstance().log(e.getMessage());
        }
        --numberOfSecondUntilEnd;
      }
    }

  }

  /**
   * Inner class to show a confirmation pop up.
   *
   */
  class ConfirmationPopUp implements Runnable {

    @Override
    public void run() {
      SCAToAmaltheaHandler.this.confirmation =
          MessageDialog.openConfirm(SCAToAmaltheaHandler.this.currentShell, title, confirmationMessage);

    }
  }

  /**
   * Inner class to show a information pop up.
   */
  class InfoPopUp implements Runnable {

    @Override
    public void run() {
      MessageDialog.openInformation(SCAToAmaltheaHandler.this.currentShell, title, infoMessage);

    }
  }

  /**
   * This method starts the timer.The timer is sceduled to run after every 15mins.Every time the timer runs it checks if
   * the eclipse job is still alive. If so it pops up a confirmation dialog asking if the user wishes to continue. If
   * the user wishes to continue the timer keeps running and keeps showing the popup after every 15 mins and if the user
   * wishes to abort then it cancels the eclipse job, cancels the timer and kills the sca.exe process.If the eclipse job
   * is not alive it cancels the timer.
   */
  private void startTimer() {
    if (getTimerDelay() == 0) {
      setTimerDelay(40 * 60 * 1000);
    }
    if (getTimerPeriod() == 0) {
      setTimerPeriod(40 * 60 * 1000);
    }
    Job eclipseJob = Job.getJobManager().currentJob();
    Timer t = new Timer();
    t.scheduleAtFixedRate(new TimerTask() {

      @Override
      public void run() {
        if ((eclipseJob.getThread() != null) && eclipseJob.getThread().isAlive()) {
          setConfirmationMessage(
              "The amalthea model generation job is still running.It might take some more time. Do you wish to continue? Press Ok to continue or cancel to abort");
          setTitle("Amalthea Job status");
          Display.getDefault().syncExec(new ConfirmationPopUp());
          if (!SCAToAmaltheaHandler.this.confirmation) {
            t.cancel();
            eclipseJob.cancel();
            Process p = UtilityForProcessHandling.getCurrentRunningProcess();
            if (p != null) {
              p.destroyForcibly();
            }
          }
        }
        else {
          t.cancel();
        }
      }
    }, getTimerDelay(), getTimerPeriod());
  }

  private static void setInfoMessage(final String message) {
    SCAToAmaltheaHandler.infoMessage = message;
  }

  private static void setTitle(final String message) {
    SCAToAmaltheaHandler.title = message;
  }

  private static void setConfirmationMessage(final String message) {
    SCAToAmaltheaHandler.confirmationMessage = message;
  }
}
