/*******************************************************************************
 * Copyright (c) 2004, 2007 Boeing.
 * 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:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.ote.core.environment;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.ExportException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import org.eclipse.osee.connection.service.IServiceConnector;
import org.eclipse.osee.connection.service.LocalConnector;
import org.eclipse.osee.framework.jdk.core.reportdata.ReportDataListener;
import org.eclipse.osee.framework.jdk.core.util.EnhancedProperties;
import org.eclipse.osee.framework.jdk.core.util.Lib;
import org.eclipse.osee.framework.jdk.core.util.Strings;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.ote.OseeLogStatusCallback;
import org.eclipse.osee.ote.core.GCHelper;
import org.eclipse.osee.ote.core.OseeTestThread;
import org.eclipse.osee.ote.core.OteProperties;
import org.eclipse.osee.ote.core.TestScript;
import org.eclipse.osee.ote.core.environment.interfaces.IAssociatedObjectListener;
import org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer;
import org.eclipse.osee.ote.core.environment.interfaces.IEnvironmentFactory;
import org.eclipse.osee.ote.core.environment.interfaces.IExecutionUnitManagement;
import org.eclipse.osee.ote.core.environment.interfaces.IRuntimeLibraryManager;
import org.eclipse.osee.ote.core.environment.interfaces.IScriptControl;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironment;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentListener;
import org.eclipse.osee.ote.core.environment.interfaces.ITestLogger;
import org.eclipse.osee.ote.core.environment.interfaces.ITestStation;
import org.eclipse.osee.ote.core.environment.interfaces.ITimeout;
import org.eclipse.osee.ote.core.environment.interfaces.ITimerControl;
import org.eclipse.osee.ote.core.framework.IRunManager;
import org.eclipse.osee.ote.core.framework.command.ICommandHandle;
import org.eclipse.osee.ote.core.framework.command.ITestContext;
import org.eclipse.osee.ote.core.framework.command.ITestServerCommand;
import org.eclipse.osee.ote.core.internal.Activator;
import org.eclipse.osee.ote.properties.OtePropertiesCore;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

/**
 * @author Andrew M. Finkbeiner
 */
public abstract class TestEnvironment implements TestEnvironmentInterface, ITestEnvironmentAccessor, ITestContext {

   private final List<ITestEnvironmentListener> envListeners = new ArrayList<>(32);
   private IExecutionUnitManagement executionUnitManagement;

   private File outDir = null;
   private final ITestStation testStation;
   private boolean batchMode = false;
   private final HashMap<String, Remote> controlInterfaces = new HashMap<>();
   private final IEnvironmentFactory factory;
   private IServiceConnector connector;
   private final IRuntimeLibraryManager runtimeManager;

   @Deprecated
   private final HashMap<Class<?>, Object> associatedObjects;
   @Deprecated
   private final HashMap<Class<?>, ArrayList<IAssociatedObjectListener>> associatedObjectListeners;
   @Deprecated
   private boolean isEnvSetup = false;
   @Deprecated
   private final List<IScriptCompleteEvent> scriptCompleteListeners = new ArrayList<>();
   @Deprecated
   private final List<IScriptSetupEvent> scriptSetupListeners = new ArrayList<>();

   private volatile boolean isShutdown = false;
   private ServiceRegistration<TestEnvironmentInterface> myRegistration;

   private UutApi uutApi;

   protected TestEnvironment(IEnvironmentFactory factory) {
      GCHelper.getGCHelper().addRefWatch(this);
      this.factory = factory;
      this.testStation = factory.getTestStation();
      this.runtimeManager = factory.getRuntimeManager();

      this.associatedObjectListeners = new HashMap<>();
      this.associatedObjects = new HashMap<>(100);
      this.batchMode = OteProperties.isOseeOteInBatchModeEnabled();

   }

   public void init(IServiceConnector connector) {
      this.connector = connector;
   }

   private void setupDefaultConnector() {
      EnhancedProperties props = new EnhancedProperties();
      try {
         props.setProperty("station", InetAddress.getLocalHost().getHostName());
      } catch (UnknownHostException ex) {
         OseeLog.log(TestEnvironment.class, Level.SEVERE, ex);
      }
      props.setProperty("date", new Date());
      props.setProperty("group", "OSEE Test Environment");
      props.setProperty("owner", OtePropertiesCore.userName.getValue());
      connector = new LocalConnector(this, Integer.toString(this.getUniqueId()), props);
   }

   public ServiceTracker getServiceTracker(String clazz, ServiceTrackerCustomizer customizer) {
      return Activator.getInstance().getServiceTracker(clazz, customizer);
   }

   @Override
   public ServiceTracker getServiceTracker(String clazz) {
      return getServiceTracker(clazz, null);
   }

   @Override
   public ICommandHandle addCommand(ITestServerCommand cmd) throws ExportException {
      return factory.getCommandManager().addCommand(cmd, this);
   }

   @Override
   public IRunManager getRunManager() {
      return factory.getRunManager();
   }

   @Override
   public IRuntimeLibraryManager getRuntimeManager() {
      return this.runtimeManager;
   }

   @Override
   public IEnvironmentFactory getEnvironmentFactory() {
      return factory;
   }

   @Override
   public boolean isInBatchMode() {
      return batchMode;
   }

   @Override
   public void setBatchMode(boolean isInBatchMode) {
      if (!OteProperties.isOseeOteInBatchModeEnabled()) {
         this.batchMode = isInBatchMode;
      }
   }

   @Override
   public void addEnvironmentListener(ITestEnvironmentListener listener) {
      envListeners.add(listener);
   }

   @Override
   public boolean addTask(EnvironmentTask task) {
      factory.getTimerControl().addTask(task, this);
      return true;
   }

   public boolean equals(ITestEnvironment testEnvironment) throws RemoteException {
      if (testEnvironment.getUniqueId() == getUniqueId()) {
         return true;
      } else {
         return false;
      }
   }

   @Override
   public long getEnvTime() {
      return getTimerCtrl().getEnvTime();
   }

   @Override
   public IExecutionUnitManagement getExecutionUnitManagement() {
      return this.executionUnitManagement;
   }

   @Override
   public ITestLogger getLogger() {
      return factory.getTestLogger();
   }

   @Override
   public List<String> getQueueLabels() {
      List<String> list = new ArrayList<>();
      list.add("Description");
      return list;
   }

   @Override
   public abstract Object getModel(String modelClassName);

   @Override
   public IScriptControl getScriptCtrl() {
      return factory.getScriptControl();
   }

   @Override
   public byte[] getScriptOutfile(String filepath) throws RemoteException {
      try {
         File file = new File(filepath);
         InputStream is = new FileInputStream(file);
         long length = file.length();
         byte[] bytes = new byte[(int) length];

         int numRead = is.read(bytes);
         if (numRead < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
         }
         is.close();
         OseeLog.log(TestEnvironment.class, Level.FINE, "going to send " + bytes.length + " bytes to the client");

         return bytes;
      } catch (Exception ex) {
         throw new RemoteException("Error retrieving the script output", ex);
      }
   }

   @Override
   public ITestStation getTestStation() {
      return testStation;
   }

   @Override
   public ITimerControl getTimerCtrl() {
      return factory.getTimerControl();
   }

   @Override
   public int getUniqueId() {
      return this.hashCode();
   }

   private final void removeAllTasks() {
      factory.getTimerControl().cancelAllTasks();
   }

   @Override
   public URL setBatchLibJar(byte[] batchJar) throws IOException {
      String path = OtePropertiesCore.userHome.getValue() + File.separator + TestEnvironment.class.getName();

      File dir = new File(path, "batchLibCache");
      if (!dir.isDirectory()) {
         dir.mkdir();
      }
      File jar = File.createTempFile("Batch", ".jar", dir);
      Lib.writeBytesToFile(batchJar, jar);
      return jar.toURI().toURL();
   }

   @Override
   public ICancelTimer setTimerFor(ITimeout listener, int time) {
      return getTimerCtrl().setTimerFor(listener, time);
   }

   @Override
   public void setupOutfileDir(String outfileDir) throws IOException {
      if (Strings.isValid(outfileDir)) {
         outDir = new File(outfileDir);
         if (!outDir.isDirectory()) {
            if (!outDir.mkdirs()) {
               throw new IOException("Failed to create the output directory");
            }
            OseeLog.logf(TestEnvironment.class, Level.INFO,
                  "Outfile Dir [%s] created.", outDir.getAbsolutePath());
         } else {
            OseeLog.logf(TestEnvironment.class, Level.FINE,
                  "Outfile Dir [%s] exists.", outDir.getAbsolutePath());
         }
      } else {
         throw new IOException("A valid outfile directory must be specified.");
      }
   }

   @Override
   public void shutdown() {
      if (isShutdown) {
         return;
      }
      isShutdown = true;
      runtimeManager.uninstall(new OseeLogStatusCallback());
      Activator.getInstance().unregisterTestEnvironment();
      // here we remove all environment tasks (emulators)
      removeAllTasks();
      if (associatedObjects != null) {
         this.associatedObjects.clear();// get rid of all models and support
      }

      OseeLog.log(TestEnvironment.class, Level.FINE, "shutting down environment");
      factory.getTimerControl().cancelTimers();
      stop();
      cleanupClassReferences();
      OseeTestThread.clearThreadReferences();
      for (ITestEnvironmentListener listener : envListeners) {
         try {
            listener.onEnvironmentKilled(this);
         } catch (Exception e) {
            OseeLog.log(TestEnvironment.class, Level.SEVERE, "exception during listener notification", e);
         }
      }
      envListeners.clear();
      if (getRunManager() != null) {
         getRunManager().clearAllListeners();
      }
   }

   protected abstract void loadExternalDrivers();

   public void startup(String outfileDir) throws Exception {
      try {
         setupOutfileDir(outfileDir);
      } catch (IOException ex) {
         throw new Exception("Error in directory setup. " + outfileDir, ex);
      }
      if (myRegistration != null) {
         myRegistration.unregister();
      }
      myRegistration = FrameworkUtil.getBundle(getClass()).getBundleContext().registerService(TestEnvironmentInterface.class, this, null);
   }

   protected void stop() {
      try {
         myRegistration.unregister();
      } catch (IllegalStateException ex) {
         // ignore if it's already unregistered
      }
   }

   protected void cleanupClassReferences() {
      OseeLog.log(TestEnvironment.class, Level.FINE, "cleanupreferences");

      System.out.println("Associated objects that are getting cleaned up.");
      for (Class<?> clazz : associatedObjects.keySet()) {
         System.out.println(clazz.toString());
      }

      if (associatedObjects != null) {
         associatedObjects.clear();
      }
      OseeLog.log(TestEnvironment.class, Level.FINE, "got the other PM REF");
      if (associatedObjectListeners != null) {
         associatedObjectListeners.clear();
      }
      GCHelper.getGCHelper().printLiveReferences();
   }

   public void setExecutionUnitManagement(IExecutionUnitManagement executionUnitManagement) {
      this.executionUnitManagement = executionUnitManagement;
   }

   @Override
   public File getOutDir() {
      return outDir;
   }

   @Override
   public Remote getControlInterface(String id) {
      return controlInterfaces.get(id);
   }

   @Override
   public void registerControlInterface(String id, Remote controlInterface) {
      controlInterfaces.put(id, controlInterface);
   }

   @Override
   public IServiceConnector getConnector() {
      return connector;
   }

   @Deprecated
   public void setEnvSetup(boolean isEnvSetup) {
      this.isEnvSetup = isEnvSetup;
   }

   @Deprecated
   public void addScriptCompleteListener(IScriptCompleteEvent scriptComplete) {
      this.scriptCompleteListeners.add(scriptComplete);
   }

   @Deprecated
   public void removeScriptCompleteListener(IScriptCompleteEvent scriptComplete) {
      this.scriptCompleteListeners.remove(scriptComplete);
   }

   @Deprecated
   public void addScriptSetupListener(IScriptSetupEvent scriptSetup) {
      this.scriptSetupListeners.add(scriptSetup);
   }

   @Deprecated
   public void removeScriptSetupListener(IScriptSetupEvent scriptSetup) {
      this.scriptSetupListeners.remove(scriptSetup);
   }

   @Deprecated
   protected boolean isEnvSetup() {
      return isEnvSetup;
   }

   @Deprecated
   /**
    * alerts the environment of an exception. The environment will take any
    * necessary actions and alert any interested
    * entities of the problem. Any runing test script will be terminated
    * 
    */
   public void handleException(Throwable t, Level logLevel) {
      handleException(t, "An exception has occurred in the environment", logLevel, true);
   }

   @Deprecated
   /**
    * @param abortScript
    *           true will cause the currently running script to abort
    */
   public void handleException(Throwable t, Level logLevel, boolean abortScript) {
      handleException(t, "An exception has occurred in the environment", logLevel, abortScript);
   }

   @Deprecated
   /**
    * alerts the environment of an exception. The environment will take any
    * necessary actions and alert any interested
    * entities of the problem
    * 
    * @param t
    *           the exception
    * @param logLevel
    *           the severity of the exception. Specifing a Level.OFF will
    * @param abortScript
    *           cause the exception to not be logged
    */
   public void handleException(Throwable t, String message, Level logLevel, boolean abortScript) {
      if (logLevel != Level.OFF) {
         OseeLog.log(TestEnvironment.class, logLevel, message, t);
      }
      if (getTestScript() != null && abortScript) {
         getTestScript().abortDueToThrowable(t);
      }
      Iterator<ITestEnvironmentListener> iter = envListeners.iterator();
      while (iter.hasNext()) {
         final ITestEnvironmentListener listener = iter.next();
         listener.onException(message, t);
      }
   }

   @Deprecated
   public void testEnvironmentCommandComplete(ICommandHandle handle) {
      for (ITestEnvironmentListener listener : envListeners) {
         try {
            listener.onTestServerCommandFinished(this, handle);
         } catch (Throwable th) {
            System.out.println(listener.getClass().getName());
            th.printStackTrace();
         }
      }
   }

   @Override
   @Deprecated
   /**
    * marks the script as ready as well as clears any objects that are
    * associated with the environment.
    */
   public synchronized void onScriptSetup() {

      for (IScriptSetupEvent listeners : scriptSetupListeners) {
         listeners.scriptSetup();
      }

      this.associatedObjects.clear();
   }

   @Deprecated
   public void removeQueueListener(ReportDataListener listener) throws RemoteException {
      factory.getReportDataControl().removeQueueListener(listener);
   }

   @Override
   @Deprecated
   public void onScriptComplete() throws InterruptedException {
      factory.getScriptControl().setScriptReady(false);

      for (int i = 0; i < scriptCompleteListeners.size(); i++) {
         try {
            scriptCompleteListeners.get(i).scriptComplete();
         } catch (Exception e) {
            OseeLog.log(TestEnvironment.class, Level.SEVERE, "problem with script complete listener", e);
         }
      }

      // here we remove all environment tasks (emulators)
      if (associatedObjects != null) {
         this.associatedObjects.clear();// get rid of all models and support
      }
   }

   @Override
   @Deprecated
   public void associateObject(Class<?> c, Object obj) {
      associatedObjects.put(c, obj);
      ArrayList<IAssociatedObjectListener> listeners = this.associatedObjectListeners.get(c);
      if (listeners != null) {
         for (int i = 0; i < listeners.size(); i++) {
            try {
               listeners.get(i).updateAssociatedListener();
            } catch (RemoteException e) {
               OseeLog.log(TestEnvironment.class, Level.SEVERE, e.getMessage(), e);
            }

         }
      }
   }

   @Override
   @Deprecated
   public Object getAssociatedObject(Class<?> c) {
      return associatedObjects.get(c);
   }

   @Override
   @Deprecated
   public Set<Class<?>> getAssociatedObjects() {
      return associatedObjects.keySet();
   }

   @Override
   @Deprecated
   /**
    * Use getRunManager().getCurrentScript() instead of this method.
    */
   public TestScript getTestScript() {
      return getRunManager().getCurrentScript();
   }

   /**
    * Causes current thread to wait until another thread invokes the {@link java.lang.Object#notify()}method or the
    * {@link java.lang.Object#notifyAll()}method for this object.
    * 
    * @param milliseconds
    * @throws InterruptedException
    */
   public void testWait(int milliseconds) {
      getRunManager().getCurrentScript().testWait(milliseconds);
   }
   
   @Override
   @Deprecated
   public void abortTestScript() {
      getRunManager().abort();
   }

   public UutApi getUutApi() {
      return uutApi;
   }

   public void setUutApi(UutApi uutApi) {
      this.uutApi = uutApi;
   }

}
