/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.uima.ruta.testing.ui.handlers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngine;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.CASException;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.impl.XmiCasDeserializer;
import org.apache.uima.cas.impl.XmiCasSerializer;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.resource.impl.ResourceManager_impl;
import org.apache.uima.resource.metadata.FsIndexDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.ruta.addons.RutaAddonsPlugin;
import org.apache.uima.ruta.engine.RutaEngine;
import org.apache.uima.ruta.ide.core.builder.RutaProjectUtils;
import org.apache.uima.ruta.ide.launching.RutaLaunchConfigurationConstants;
import org.apache.uima.ruta.ide.launching.RutaLaunchConstants;
import org.apache.uima.ruta.testing.evaluator.ICasEvaluator;
import org.apache.uima.ruta.testing.preferences.TestingPreferenceConstants;
import org.apache.uima.ruta.testing.ui.views.TestCasData;
import org.apache.uima.ruta.testing.ui.views.TestPageBookView;
import org.apache.uima.ruta.testing.ui.views.TestViewPage;
import org.apache.uima.ruta.testing.ui.views.evalDataTable.TypeEvalData;
import org.apache.uima.ruta.testing.ui.views.util.EvalDataProcessor;
import org.apache.uima.ruta.type.EvalAnnotation;
import org.apache.uima.util.CasCreationUtils;
import org.apache.uima.util.FileUtils;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
import org.xml.sax.SAXException;

public class RerunActionHandler implements IHandler {

  private class DebugJobChangeAdapter extends JobChangeAdapter {

    private TestViewPage page;

    DebugJobChangeAdapter(TestViewPage page) {
      super();
      this.page = page;
    }

    @Override
    public void done(IJobChangeEvent event) {
      if (event.getResult().isOK()) {
        page.getControl().getDisplay().asyncExec(new Runnable() {
          @Override
          public void run() {
            page.updateInfoPanel();
          }
        });
      }
    }
  }

  /**
   * Handler that runs the script to be tested and updates the GUI.
   */
  private class RerunHandlerJob extends Job {
    ExecutionEvent event;

    private final String viewCasName;

    private List<String> excludedTypes;

    private List<String> includedTypes;

    private boolean debug;

    RerunHandlerJob(ExecutionEvent event, String scriptName, String viewCasName,
            List<String> excludedTypes, List<String> includedTypes, boolean debug) {
      super("Testing " + scriptName + "...");
      this.event = event;
      this.viewCasName = viewCasName;
      this.excludedTypes = excludedTypes;
      this.includedTypes = includedTypes;
      this.debug = debug;
      setUser(true);
    }

    @Override
    public IStatus run(IProgressMonitor monitor) {

      // handle GUI
      final TestPageBookView testPageView = (TestPageBookView) HandlerUtil.getActivePart(event);
      final TestViewPage debugPage = (TestViewPage) testPageView.getCurrentPage();
      testPageView.showBusy(true);

      // init variables
      IResource r = debugPage.getResource();
      final IFile fScript = (IFile) r;
      final IProject project = r.getProject();
      IPath engineDescriptorPath = null;
      IPath typeSystemDescriptorPath = null;
      try {
        ClassLoader classLoader = RutaProjectUtils.getClassLoader(project);
        engineDescriptorPath = RutaProjectUtils.getAnalysisEngineDescriptorPath(r.getLocation(),
                project, classLoader);
        typeSystemDescriptorPath = RutaProjectUtils
                .getTypeSystemDescriptorPath(fScript.getLocation(), project, classLoader);
      } catch (CoreException e) {
        RutaAddonsPlugin.error(e);
      }
      // show message
      @SuppressWarnings({ "unchecked", "rawtypes" })
      ArrayList<TestCasData> testCasData = (ArrayList) debugPage.getViewer().getInput();
      int numFiles = testCasData.size();
      monitor.beginTask("Running evaluation, please wait", numFiles);

      // switch usage mode: old (only Ruta) vs. new (supports java/uimaFIT AEs)
      IPreferenceStore store = RutaAddonsPlugin.getDefault().getPreferenceStore();
      boolean javaSupportMode = store.getBoolean(TestingPreferenceConstants.EXTEND_CLASSPATH);
      if (!javaSupportMode) {
        // only Ruta mode (classpath NOT expanded)
        IStatus status = evalRutaOnlyScript(monitor, testPageView, debugPage, fScript, project,
                engineDescriptorPath, testCasData);
        if (status.getSeverity() == IStatus.ERROR) {
          Display current = Display.getCurrent();
          if (current != null) {
            Shell shell = current.getActiveShell();
            MessageDialog.openWarning(shell, "Error", status.getMessage());
          }
        }
        return status;
      } else {
        // * write clean run files into a temp directory, remember file names
        // TODO this approach (may) causes problems, when Java/uimaFIT engines have their own
        // typesystems...
        IStatus status = evalRutaWithClassPathScript(monitor, testPageView, debugPage, fScript,
                project, typeSystemDescriptorPath, testCasData);
        return status;
      }
    }

    private IStatus evalRutaWithClassPathScript(IProgressMonitor monitor,
            final TestPageBookView testPageView, final TestViewPage debugPage, final IFile fScript,
            final IProject project, IPath typeSystemDescriptorPath,
            ArrayList<TestCasData> testCasData) {
      final IPath cleanInputPath = project.getLocation()
              .append(RutaProjectUtils.getDefaultTestLocation())
              .append(RutaProjectUtils.getDefaultCleanTestLocation());
      clearFolder(project, cleanInputPath);
      writeCleanInputFiles(testCasData, project, typeSystemDescriptorPath, cleanInputPath, monitor);
      if (monitor.isCanceled()) {
        // TODO call monitor.done()
        return Status.CANCEL_STATUS;
      }

      // * apply script to the clean run files
      final IPath runTestPath = project.getLocation()
              .append(RutaProjectUtils.getDefaultTestLocation())
              .append(RutaProjectUtils.getDefaultTempTestLocation());
      clearFolder(project, runTestPath);
      runWithJVM(monitor, fScript, cleanInputPath, runTestPath);

      try {
        // * for each (goldFile, runFile)-pair:
        XMLInputSource in = new XMLInputSource(typeSystemDescriptorPath.toPortableString());
        TypeSystemDescription tsd = UIMAFramework.getXMLParser().parseTypeSystemDescription(in);
        ClassLoader classLoader = RutaProjectUtils.getClassLoader(project);
        ResourceManager resourceManager = new ResourceManager_impl(classLoader);
        tsd.resolveImports(resourceManager);
        CAS runCas = CasCreationUtils.createCas(tsd, null, null);
        CAS goldCas = CasCreationUtils.createCas(tsd, null, null);
        for (TestCasData td : testCasData) {
          // init etc
          runCas.reset();
          goldCas.reset();
          // deserialize CASes
          IPath path2RunFile = runTestPath.append(td.getPath().toFile().getName());
          String runFilePath = path2RunFile.toPortableString();
          File runFile = new File(runFilePath);
          deserializeCASs(goldCas, td, runCas, runFile);
          runCas = runCas.getView(viewCasName);
          goldCas = goldCas.getView(viewCasName);
          // ** create TP, FP, FN annotations
          // ** collect results and gather eval data
          evalLogicAndUpdateGUI(monitor, testPageView, debugPage, fScript, project, runCas, goldCas,
                  td);
          if (monitor.isCanceled()) {
            return Status.CANCEL_STATUS;
          }
        }
      } catch (Exception e) {
        RutaAddonsPlugin.error(e);
        monitor.done();
        testPageView.showBusy(false);
        return new Status(Status.ERROR, RutaAddonsPlugin.PLUGIN_ID,
                "Error during testing. See Error View for details.");
      }
      monitor.done();
      return Status.OK_STATUS;
    }

    /**
     * This method assumes that gold annotations have already been removed from the files. It just
     * applies the script to the files.
     * 
     * @param monitor
     * @param scriptFile
     * @param cleanInputPath
     */
    private void runWithJVM(IProgressMonitor monitor, IFile scriptFile, IPath cleanInputPath,
            IPath runOutputPath) {
      monitor.setTaskName(
              String.format("Processing script \"%s\" [w classpatch ext.].", scriptFile.getName()));

      IProject project = scriptFile.getProject();

      // init args
      String inputDirPath = null;
      String outputDirPath = null;
      if (cleanInputPath != null) {
        inputDirPath = cleanInputPath.toFile().getAbsolutePath();
      } else {
        // TODO throw exception
        return;
      }
      if (runOutputPath != null) {
        outputDirPath = runOutputPath.toFile().getAbsolutePath();
      } else {
        // TODO throw exception
        return;
      }

      try {
        ClassLoader classLoader = RutaProjectUtils.getClassLoader(project);
        IPath descriptorPath = RutaProjectUtils
                .getAnalysisEngineDescriptorPath(scriptFile.getLocation(), project, classLoader);
        String descriptorAbsolutePath = descriptorPath.toFile().getAbsolutePath();
        ILaunchManager mgr = DebugPlugin.getDefault().getLaunchManager();
        ILaunchConfigurationType type = mgr
                .getLaunchConfigurationType(RutaLaunchConfigurationConstants.ID_RUTA_SCRIPT);

        ILaunchConfigurationWorkingCopy copy = type.newInstance(null,
                scriptFile.getName() + ".Testing");
        // do not use RutaLaunchConstants.ARG_INPUT_FOLDER here
        copy.setAttribute(RutaLaunchConstants.INPUT_FOLDER, inputDirPath);
        // do not use RutaLaunchConstants.ARG_OUTPUT_FOLDER here
        copy.setAttribute(RutaLaunchConstants.OUTPUT_FOLDER, outputDirPath);
        copy.setAttribute(RutaLaunchConstants.DESCRIPTOR, descriptorAbsolutePath);
        copy.setAttribute(RutaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName());
        ILaunchConfiguration lc = copy.doSave();

        String mode = ILaunchManager.RUN_MODE;
        if (debug) {
          mode = ILaunchManager.DEBUG_MODE;
        }
        ILaunch launch = new Launch(lc, mode, null);

        ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();

        ILaunch launched = launchConfiguration.launch(ILaunchManager.RUN_MODE, monitor);

        while (!launched.isTerminated()) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {
            RutaAddonsPlugin.error(e);
          }
        }

      } catch (CoreException e) {
        RutaAddonsPlugin.error(e);
      }
    }

    private void clearFolder(final IProject project, final IPath folderPath) {
      FileUtils.deleteAllFiles(folderPath.toFile()); // clear folder
      try {
        project.getFolder(folderPath.makeRelativeTo(project.getLocation()))
                .refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
      } catch (CoreException e1) {
        e1.printStackTrace();
      }
    }

    private void deserializeCASs(CAS tdCas, TestCasData td, CAS casA, File fileA)
            throws FileNotFoundException, SAXException, IOException {
      if (!fileA.exists()) {
        throw new FileNotFoundException(fileA.getAbsolutePath());
      }
      FileInputStream inputStream = null;
      try {
        inputStream = new FileInputStream(new File(td.getPath().toPortableString()));
        XmiCasDeserializer.deserialize(inputStream, tdCas, true);
      } finally {
        if (inputStream != null) {
          inputStream.close();
        }
      }
      try {
        inputStream = new FileInputStream(fileA);
        XmiCasDeserializer.deserialize(inputStream, casA, true);
      } finally {
        if (inputStream != null) {
          inputStream.close();
        }
      }
    }

    private void writeCleanInputFiles(List<TestCasData> testCasData, IProject project,
            IPath tsDescriptorPath, IPath cleanInputPath, IProgressMonitor monitor) {
      try {
        // create CAS:
        XMLInputSource in = new XMLInputSource(tsDescriptorPath.toPortableString());
        TypeSystemDescription tsd = UIMAFramework.getXMLParser().parseTypeSystemDescription(in);
        ClassLoader classLoader = RutaProjectUtils.getClassLoader(project);
        ResourceManager resourceManager = new ResourceManager_impl(classLoader);
        tsd.resolveImports(resourceManager);
        CAS cleanCas = getEmptyCas(tsd);

        for (TestCasData td : testCasData) {
          // init etc
          cleanCas.reset(); // clean
          // deserialize CASes
          FileInputStream inputStreamRun = null;
          try {
            inputStreamRun = new FileInputStream(new File(td.getPath().toPortableString()));
            XmiCasDeserializer.deserialize(inputStreamRun, cleanCas, true);
          } finally {
            if (inputStreamRun != null) {
              inputStreamRun.close();
            }
          }
          cleanCas = cleanCas.getView(viewCasName);
          prepareCas(cleanCas);
          // store clean CAS
          IPath path2CleanFile = computeCleanPath(cleanInputPath, td);
          String fPath = path2CleanFile.toPortableString();
          File cleanFile = new File(fPath);
          writeXmi(cleanCas, cleanFile);

          td.setResultPath(path2CleanFile);

          if (monitor.isCanceled()) {
            return;
          }
        }

        cleanCas.release();
        project.getFolder(cleanInputPath.makeRelativeTo(project.getLocation()))
                .refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
      } catch (Exception e) {
        RutaAddonsPlugin.error(e);
      }
    }

    private IPath computeCleanPath(IPath cleanInputPath, TestCasData td) {
      return cleanInputPath.append(td.getPath().removeFileExtension().lastSegment() + ".xmi");
    }

    private IStatus evalRutaOnlyScript(IProgressMonitor monitor,
            final TestPageBookView testPageView, final TestViewPage debugPage, IFile fScript,
            final IProject project, final IPath engineDescriptorPath,
            ArrayList<TestCasData> testCasData) {
      try {
        // create AE:
        XMLInputSource in = new XMLInputSource(engineDescriptorPath.toPortableString());
        ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in);
        AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(specifier);

        if (debug) {
          ae.setConfigParameterValue(RutaEngine.PARAM_DEBUG, true);
          ae.setConfigParameterValue(RutaEngine.PARAM_DEBUG_WITH_MATCHES, true);
          ae.setConfigParameterValue(RutaEngine.PARAM_PROFILE, true);
          ae.setConfigParameterValue(RutaEngine.PARAM_STATISTICS, true);
          ae.setConfigParameterValue(RutaEngine.PARAM_CREATED_BY, true);
        }
        ae.reconfigure();

        // create (empty) CAS objects:
        String desc = null;
        desc = engineDescriptorPath.toPortableString();
        XMLInputSource in2 = new XMLInputSource(desc);
        Object descriptor = UIMAFramework.getXMLParser().parse(in2);
        CAS runCas = getEmptyCas(descriptor);
        CAS testCas = getEmptyCas(descriptor);

        for (TestCasData td : testCasData) {
          // init td etc
          runCas.reset();
          testCas.reset();
          String elementName = fScript.getLocation().lastSegment();
          monitor.setTaskName("Processing [w/o classpatch ext.] " + td.getPath().lastSegment());
          int lastIndexOf = elementName.lastIndexOf(RutaEngine.SCRIPT_FILE_EXTENSION);
          if (lastIndexOf != -1) {
            elementName = elementName.substring(0, lastIndexOf);
          }
          // deserialize CASes
          FileInputStream inputStreamTest = null;
          try {
            inputStreamTest = new FileInputStream(new File(td.getPath().toPortableString()));
            XmiCasDeserializer.deserialize(inputStreamTest, testCas, true);
          } finally {
            if (inputStreamTest != null) {
              inputStreamTest.close();
            }
          }
          FileInputStream inputStreamRun = null;
          try {
            inputStreamRun = new FileInputStream(new File(td.getPath().toPortableString()));
            XmiCasDeserializer.deserialize(inputStreamRun, runCas, true);
          } finally {
            if (inputStreamRun != null) {
              inputStreamRun.close();
            }
          }
          testCas = testCas.getView(viewCasName);
          runCas = runCas.getView(viewCasName);

          // gather uima eval-types
          prepareCas(runCas);

          // process run cas and evaluate it
          ae.process(runCas);
          evalLogicAndUpdateGUI(monitor, testPageView, debugPage, fScript, project, runCas, testCas,
                  td);
          if (monitor.isCanceled()) {
            ae.destroy();
            return Status.CANCEL_STATUS;
          }
        }
        ae.destroy();
      } catch (Exception e) {
        RutaAddonsPlugin.error(e);
        monitor.done();
        testPageView.showBusy(false);
        return new Status(Status.ERROR, RutaAddonsPlugin.PLUGIN_ID,
                "Error during testing. See Error View for details.");
      }

      monitor.done();
      testPageView.showBusy(false);
      return Status.OK_STATUS;
    }

    private void prepareCas(CAS cas) {
      if (!includedTypes.isEmpty()) {
        // exclude all other types if there are some included types
        excludedTypes = new ArrayList<String>();
        List<Type> types = cas.getTypeSystem().getProperlySubsumedTypes(cas.getAnnotationType());
        for (Type type : types) {
          if (!includedTypes.contains(type.getName())) {
            excludedTypes.add(type.getName());
          }
        }
      }
      if (includedTypes.isEmpty() && excludedTypes.isEmpty()) {
        // remove all annotation in default settings
        String documentText = cas.getDocumentText();
        cas.reset();
        cas.setDocumentText(documentText);
      } else {
        List<AnnotationFS> toRemove = new LinkedList<AnnotationFS>();
        AnnotationIndex<AnnotationFS> annotationIndex = cas.getAnnotationIndex();
        for (AnnotationFS annotationFS : annotationIndex) {
          Type type = annotationFS.getType();
          String typeName = type.getName();
          if (includedTypes.contains(typeName) || !excludedTypes.contains(typeName)) {
            toRemove.add(annotationFS);
          }
        }
        for (AnnotationFS each : toRemove) {
          if (!cas.getDocumentAnnotation().equals(each)) {
            cas.removeFsFromIndexes(each);
          }
        }
      }
    }

    private void evalLogicAndUpdateGUI(IProgressMonitor monitor,
            final TestPageBookView testPageView, final TestViewPage debugPage, IFile fScript,
            final IProject project, CAS runCas, CAS goldCas, TestCasData td)
            throws AnalysisEngineProcessException, CASException, IOException, SAXException,
            CoreException {
      // memento for prefs
      IPreferenceStore store = RutaAddonsPlugin.getDefault().getPreferenceStore();
      String factoryName = store.getString(TestingPreferenceConstants.EVALUATOR_FACTORY);
      ICasEvaluator evaluator = RutaAddonsPlugin.getCasEvaluatorFactoryById(factoryName)
              .createEvaluator();
      boolean includeSubtypes = store.getBoolean(TestingPreferenceConstants.INCLUDE_SUBTYPES);
      boolean useAllTypes = store.getBoolean(TestingPreferenceConstants.ALL_TYPES);

      CAS resultCas = evaluator.evaluate(goldCas, runCas, excludedTypes, includeSubtypes,
              useAllTypes);

      // store results
      IPath path2Test = td.getPath().removeLastSegments(1);

      monitor.setTaskName("Actually evaluating " + td.getPath().lastSegment());

      IPath estimatedTestPath = project.getFullPath()
              .append(RutaProjectUtils.getDefaultTestLocation());
      IPath path2recource = fScript.getFullPath();
      IPath projectRelativePath2Script = path2recource.removeFirstSegments(2);
      IPath estimatedTestFolderPath = estimatedTestPath
              .append(projectRelativePath2Script.removeFileExtension());

      IPath path2Result = path2Test.append(TestCasData.RESULT_FOLDER);
      IPath path2ResultFile = path2Result
              .append(td.getPath().removeFileExtension().lastSegment() + ".result.xmi");

      if (!path2Test.toOSString().contains(estimatedTestFolderPath.toOSString())) {
        path2Result = project.getLocation().append(RutaProjectUtils.getDefaultTestLocation())
                .append(RutaProjectUtils.getDefaultTempTestLocation());
        path2ResultFile = path2Result
                .append(td.getPath().removeFileExtension().lastSegment() + ".result.xmi");
      }

      File resultFile = new File(path2ResultFile.toPortableString());
      writeXmi(resultCas, resultFile);

      td.setResultPath(path2ResultFile);

      // finally, calculate eval data and show it in the GUI
      EvalDataProcessor.calculateEvaluatData(td, resultCas);

      testPageView.getDefaultPage().getControl().getDisplay().asyncExec(new Runnable() {
        @Override
        public void run() {
          debugPage.getViewer().refresh();
        }
      });
      monitor.worked(1);
      project.getFolder(path2Result.makeRelativeTo(project.getLocation()))
              .refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
      runCas.release();
      goldCas.release();
      resultCas.release();
    }

    private CAS getEmptyCas(Object descriptor)
            throws ResourceInitializationException, InvalidXMLException {
      CAS testCas = null;
      if (descriptor instanceof AnalysisEngineDescription) {
        testCas = CasCreationUtils.createCas((AnalysisEngineDescription) descriptor);
      } else if (descriptor instanceof TypeSystemDescription) {
        TypeSystemDescription tsDesc = (TypeSystemDescription) descriptor;
        tsDesc.resolveImports();
        testCas = CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[0]);
      }
      return testCas;
    }
  }

  @Override
  public void addHandlerListener(IHandlerListener handlerListener) {

  }

  @Override
  public void dispose() {

  }

  @Override
  public Object execute(ExecutionEvent event) throws ExecutionException {
    TestPageBookView debugView = (TestPageBookView) HandlerUtil.getActivePart(event);
    if (!(debugView.getCurrentPage() instanceof TestViewPage)) {
      return Status.CANCEL_STATUS;
    }
    TestViewPage debugPage = (TestViewPage) debugView.getCurrentPage();
    // set debug by preference
    boolean debug = true;
    String viewCasName = debugPage.getSelectedViewCasName();
    String scriptName = debugPage.getResource().getLocation().lastSegment();
    RerunHandlerJob job = new RerunHandlerJob(event, scriptName, viewCasName,
            debugPage.getExcludedTypes(), debugPage.getIncludedTypes(), debug);

    job.addJobChangeListener(new DebugJobChangeAdapter(debugPage) {
    });

    job.schedule();

    return null;
  }

  private static void writeXmi(CAS aCas, File file) throws IOException, SAXException {
    FileOutputStream out = null;
    try {
      file.getParentFile().mkdirs();
      out = new FileOutputStream(file);
      XmiCasSerializer.serialize(aCas, out);
    } catch (Exception e) {
      RutaAddonsPlugin.error(e);
    } finally {
      if (out != null) {
        out.close();
      }
    }
  }

  @Override
  public boolean isEnabled() {
    return true;
  }

  @Override
  public boolean isHandled() {
    return true;
  }

  @Override
  public void removeHandlerListener(IHandlerListener handlerListener) {

  }

  /**
   * 
   * @param data
   *          will be filled with results
   * @param resultCas
   *          must contain TP, FP, FN annotations
   */
  public void calculateEvaluatData(TestCasData data, CAS resultCas) {
    data.setEvaluationStatus(true);
    TypeSystem ts = resultCas.getTypeSystem();
    Type falsePositiveType = ts.getType(ICasEvaluator.FALSE_POSITIVE);
    Type falseNegativeType = ts.getType(ICasEvaluator.FALSE_NEGATIVE);
    Type truePositiveType = ts.getType(ICasEvaluator.TRUE_POSITIVE);

    int falsePositiveCount = resultCas.getAnnotationIndex(falsePositiveType).size();
    int falseNegativeCount = resultCas.getAnnotationIndex(falseNegativeType).size();
    int truePositiveCount = resultCas.getAnnotationIndex(truePositiveType).size();

    data.setTruePositiveCount(truePositiveCount);
    data.setFalsePositiveCount(falsePositiveCount);
    data.setFalseNegativeCount(falseNegativeCount);

    HashMap<String, TypeEvalData> map = new HashMap<String, TypeEvalData>();

    AnnotationIndex<AnnotationFS> index = resultCas.getAnnotationIndex(truePositiveType);

    FSIterator<AnnotationFS> iter = index.iterator();

    while (iter.isValid()) {
      EvalAnnotation a = (EvalAnnotation) iter.next();
      Annotation original = a.getOriginal();
      Type originalType = original.getType();

      if (map.containsKey(originalType.getName())) {
        TypeEvalData element = map.get(originalType.getName());
        int oldCount = element.getTruePositives();
        element.setTruePositives(oldCount + 1);
      } else {
        TypeEvalData newData = new TypeEvalData(originalType.getName(), 1, 0, 0);
        map.put(originalType.getName(), newData);
      }
    }

    index = resultCas.getAnnotationIndex(falsePositiveType);
    iter = index.iterator();

    while (iter.isValid()) {
      EvalAnnotation a = (EvalAnnotation) iter.next();
      Annotation original = a.getOriginal();
      Type originalType = original.getType();

      if (map.containsKey(originalType.getName())) {
        TypeEvalData element = map.get(originalType.getName());
        int oldCount = element.getFalsePositives();
        element.setFalsePositives(oldCount + 1);
      } else {
        TypeEvalData newData = new TypeEvalData(originalType.getName(), 0, 1, 0);
        map.put(originalType.getName(), newData);
      }
    }

    index = resultCas.getAnnotationIndex(falseNegativeType);
    iter = index.iterator();

    while (iter.isValid()) {
      EvalAnnotation a = (EvalAnnotation) iter.next();
      Annotation original = a.getOriginal();
      Type originalType = original.getType();

      if (map.containsKey(originalType.getName())) {
        TypeEvalData element = map.get(originalType.getName());
        int oldCount = element.getFalseNegatives();
        element.setFalseNegatives(oldCount + 1);
      } else {
        TypeEvalData newData = new TypeEvalData(originalType.getName(), 0, 0, 1);
        map.put(originalType.getName(), newData);
      }
    }

    data.setTypeEvalData(map);
  }

}
