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

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.codehaus.jackson.annotate.JsonProperty;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osee.framework.jdk.core.util.Lib;
import org.eclipse.osee.framework.jdk.core.util.xml.XMLStreamWriterUtil;
import org.eclipse.osee.framework.plugin.core.util.ExportClassLoader;
import org.eclipse.osee.ote.Configuration;
import org.eclipse.osee.ote.ConfigurationItem;
import org.eclipse.osee.ote.ConfigurationStatus;
import org.eclipse.osee.ote.OTEServerRuntimeCache;
import org.eclipse.osee.ote.OTEStatusCallback;
import org.eclipse.osee.ote.core.OseeURLClassLoader;
import org.eclipse.osee.ote.core.ServiceUtility;
import org.eclipse.osee.ote.core.environment.interfaces.IRuntimeLibraryManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;

/**
 * When starting bundles users can specify an OTE-StartLevel: <int value> in the manifest of a bundle, if there are issues 
 * with the order in which bundles need to be started.  The list of bundles to start will simply be sorted by that value, 
 * the default value is 0.  This was implemented to work around a deadlock issue that can happen when you call Bundle.start()
 * and there is a conflict with 'component resolving thread'.  By waiting till the end to load the bundles that can cause the issue
 * we avoid the deadlock issue which has a default 5 second time limit.
 * 
 * @author Andrew M. Finkbeiner
 *
 */
public class OTEBundleLoader implements IRuntimeLibraryManager{

   public static final String MANIFEST_ENTRY_OTE_STARTLEVEL = "OTE-StartLevel";
   
   private final List<Bundle> installedBundles;
   private final Collection<Bundle> runningBundles;
   private final Map<String, String> bundleNameToMd5Map;
   private final BundleContext context;
   
   private URLClassLoader scriptClassLoader;
   private OTEServerRuntimeCache serverRuntimeCache;

   public void bindOTEServerRuntimeCache(OTEServerRuntimeCache serverRuntimeCache){
      this.serverRuntimeCache = serverRuntimeCache;
   }
   
   public void unbindOTEServerRuntimeCache(OTEServerRuntimeCache serverRuntimeCache){
      this.serverRuntimeCache = serverRuntimeCache;
   }
   
   public OTEBundleLoader() {
      this.context = FrameworkUtil.getBundle(getClass()).getBundleContext();
      this.installedBundles = new LinkedList<>();
      this.runningBundles = new LinkedList<>();
      this.bundleNameToMd5Map = new HashMap<>();
   }

   @Override
   public boolean install(Configuration oteConfiguration, OTEStatusCallback<ConfigurationStatus> statusCallback) {
      boolean pass = true;
      for (ConfigurationItem bundleDescription : oteConfiguration.getItems()) {
         String bundleName = bundleDescription.getSymbolicName();
         try {
            boolean exists = false;
            for (Bundle bundle : runningBundles) {
               if (bundle.getSymbolicName().equals(bundleName)) {
                  exists = true;
                  break;
               }
            }
            if (!exists) {
               Bundle bundle = Platform.getBundle(bundleDescription.getSymbolicName());
               if (bundle == null) {
                  Bundle installedBundle;
                  File bundleData = acquireSystemLibraryStream(bundleDescription);
                  installedBundle = context.installBundle("reference:" + bundleData.toURI().toURL().toExternalForm());
                  bundleNameToMd5Map.put(bundleName, bundleDescription.getMd5Digest());
                  installedBundles.add(installedBundle);
               } 
            }
            statusCallback.log("installed " + bundleName);
         } catch (BundleException ex){
            if(ex.getType() == BundleException.DUPLICATE_BUNDLE_ERROR){
               statusCallback.log(String.format("Duplicate bundle [%s].", bundleName));
            } else {
               statusCallback.error(String.format("Unable to load [%s].", bundleName), ex);
               pass = false;
            }
         } catch (Throwable th) {
            statusCallback.error(String.format("Unable to load [%s].", bundleName), th);
            pass = false;
         } finally {
            statusCallback.incrememtUnitsWorked(1);
         }
      }
      return pass;
   }

   @Override
   public boolean acquireBundles(Configuration oteConfiguration, OTEStatusCallback<ConfigurationStatus> statusCallback) {
      boolean pass = true;
      for (ConfigurationItem bundleDescription : oteConfiguration.getItems()) {
         String bundleName = bundleDescription.getSymbolicName();
         File bundleData = null;
         try{
            bundleData = acquireSystemLibraryStream(bundleDescription);
         } catch (Exception e) {
            pass = false;
            statusCallback.error("Failed to aquire bundle from client.", e);
         }
         finally {
            if(bundleData == null){
               pass = false;
               statusCallback.error("Failed to downloaded bundle " + bundleName);
            }
            statusCallback.incrememtUnitsWorked(1);
         }
         statusCallback.log("downloaded " + bundleName);
      }
      return pass;
   }
   
   @Override
   public boolean start(OTEStatusCallback<ConfigurationStatus> statusCallback) {
      boolean pass = true;
      sortBundles(installedBundles);
      Iterator<Bundle> iter = installedBundles.iterator();
      while (iter.hasNext()) {
         Bundle bundle = iter.next();
         try {
            String entry = bundle.getHeaders().get("Fragment-Host");
            if (entry == null) {
               int bundleState = bundle.getState();
               if(bundleState != Bundle.ACTIVE) {
                  bundle.start();
               } 
            }
            // We got here because bundle.start did not exception
            runningBundles.add(bundle);
            iter.remove();
            statusCallback.log("started " + bundle.getSymbolicName());
         } catch (BundleException ex) {
            pass = false;
            statusCallback.error("Failed to start " + bundle.getSymbolicName(), ex);
         } finally {
            statusCallback.incrememtUnitsWorked(1);
         }
      }
      return pass;
   }

   private void sortBundles(List<Bundle> installedBundles2) {
	   Collections.sort(installedBundles, new Comparator<Bundle>() {
			@Override
			public int compare(Bundle arg0, Bundle arg1) {
				int startLevel0 = getStartLevel(arg0);
				int startLevel1 = getStartLevel(arg1);
				if(startLevel0 != 0 || startLevel1 != 0){
				return startLevel0 - startLevel1;
				} else {
				   return arg0.getSymbolicName().compareTo(arg1.getSymbolicName());
				}
			}
			
			private int getStartLevel(Bundle arg0) {
				String level = arg0.getHeaders().get(MANIFEST_ENTRY_OTE_STARTLEVEL);
				if(level == null){
					return 0;
				} else {
					try {
						return Integer.parseInt(level);
					} catch (NumberFormatException ex) {
						return 0;
					}
				}
			}
		});
   }

   @Override
   public boolean uninstall(OTEStatusCallback<ConfigurationStatus> statusCallback) {
      boolean result = true;
      for (Bundle bundle : installedBundles) {
         try {
            bundle.uninstall();
         } catch (BundleException ex) {
            result = false;
            statusCallback.error("Failed to uninstall " + bundle.getSymbolicName(), ex);
         }
      }
      installedBundles.clear();

      for (Bundle bundle : runningBundles) {
         try {
            String entry = bundle.getHeaders().get("Fragment-Host");
        	if (entry == null) {
        	   bundle.stop();
        	}
            bundle.uninstall();
         } catch (BundleException ex) {
            result = false;
            statusCallback.error("Failed to stop and uninstall " + bundle.getSymbolicName(), ex);
         }
      }
      runningBundles.clear();
      
      return result;
   }

   private File acquireSystemLibraryStream(ConfigurationItem bundleDescription) throws Exception {
      File file = serverRuntimeCache.get(bundleDescription.getSymbolicName(), bundleDescription.getMd5Digest());
      if (file == null) {
         InputStream servedBundleIn = new URL(bundleDescription.getLocationUrl()).openConnection().getInputStream();
         file = serverRuntimeCache.save(bundleDescription.getSymbolicName(), bundleDescription.getMd5Digest(), servedBundleIn);
         servedBundleIn.close();
      }
      return file;
   }

   public void dispose() {
      bundleNameToMd5Map.clear();
      installedBundles.clear();
      runningBundles.clear();
   }

   @Override
   public boolean installed() {
      return installedBundles.size() > 0 || runningBundles.size() > 0;
   }

   @Override
   public void clearJarCache() {
      serverRuntimeCache.clearJarCache();
   }
   
   @Override
   public void resetScriptLoader(Configuration oteConfiguration, String[] classPaths) throws Exception {
      List<URL> urls = new ArrayList<>();
      if(oteConfiguration != null){
         for(ConfigurationItem item:oteConfiguration.getItems()){
            File file = serverRuntimeCache.get(item.getSymbolicName(), item.getMd5Digest());
            if(file != null){
               urls.add(file.toURI().toURL());
            }
         }
      }
      URL[] urlArray = urls.toArray(new URL[urls.size()+classPaths.length]);
      URL[] urlClassPaths = Lib.getUrlFromString(classPaths);
      System.arraycopy(urlClassPaths, 0, urlArray, urls.size(), urlClassPaths.length);
      scriptClassLoader = new OseeURLClassLoader("Script ClassLoader", urlArray, ExportClassLoader.getInstance());
   }

   @Override
   public Class<?> loadFromScriptClassLoader(String path) throws ClassNotFoundException {
      if (scriptClassLoader == null) {
         return loadFromRuntimeLibraryLoader(path);
      }
      Class<?> scriptClass = scriptClassLoader.loadClass(path);
      return scriptClass;
   }

   @Override
   public Class<?> loadFromRuntimeLibraryLoader(String clazz) throws ClassNotFoundException {
      return ExportClassLoader.getInstance().loadClass(clazz);
   }

   @Override
   public void toXml(XMLStreamWriter writer) throws XMLStreamException {
      writer.writeStartElement("RuntimeVersions");
      for (String bundleVersion : getBundleVersions()) {
         XMLStreamWriterUtil.writeElement(writer, "Version", bundleVersion);
      }
      writer.writeEndElement();
   }

   @JsonProperty
   public List<String> getBundleVersions() {
       Bundle[] bundles = ServiceUtility.getContext().getBundles();
       List<String> versions = new ArrayList<>();
       for(Bundle bundle: bundles ){
           String version = bundle.getHeaders().get("Bundle-Version");
           String implVersion = bundle.getHeaders().get("Implementation-Version");
           if (version != null && implVersion != null) {
               versions.add(String.format("%s_%s_%s", bundle.getSymbolicName(), version, implVersion));
           } else if (version != null){
               versions.add(String.format("%s_%s", bundle.getSymbolicName(), version));
           } else {
               versions.add(String.format("%s", bundle.getSymbolicName()));
           }
       }
       Collections.sort(versions);
       return versions;
   }

   @Override
   public ClassLoader getClassLoader() {
      if (scriptClassLoader == null) {
         return ExportClassLoader.getInstance();
      } else {
         return scriptClassLoader;
      }
   }

}
