/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.device;

import java.io.InputStream;
import java.util.Dictionary;
import java.util.Vector;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.service.device.DriverLocator;
import org.osgi.service.log.LogService;
import org.osgi.util.tracker.ServiceTracker;

/**
 * DriverLocatorTracker class. This class tracks all DriverLocator services.
 *
 */
public class DriverLocatorTracker extends ServiceTracker {
	protected final static String clazz = "org.osgi.service.device.DriverLocator"; //$NON-NLS-1$

	/** DeviceManager object. */
	protected Activator manager;

	/** LogService object */
	protected LogTracker log;

	/** List of bundles to be uninstalled. */
	protected Vector bundles;

	/**
	 * Create the DriverLocatorTracker.
	 *
	 * @param context Device manager bundle context.
	 * @param log LogService object
	 */
	public DriverLocatorTracker(Activator manager) {
		super(manager.context, clazz, null);

		this.manager = manager;
		log = manager.log;
		bundles = new Vector(10, 10);

		if (Activator.DEBUG) {
			log.log(LogService.LOG_DEBUG, "DriverLocatorTracker constructor"); //$NON-NLS-1$
		}

		open();
	}

	/**
	 * A service is being added to the ServiceTracker.
	 *
	 * <p>This method is called before a service which matched
	 * the search parameters of the ServiceTracker is
	 * added to the ServiceTracker. This method should return the
	 * service object to be tracked for this ServiceReference.
	 * The returned service object is stored in the ServiceTracker
	 * and is available from the getService and getServices
	 * methods.
	 *
	 * @param reference Reference to service being added to the ServiceTracker.
	 * @return The service object to be tracked for the
	 * ServiceReference or <tt>null</tt> if the ServiceReference should not
	 * be tracked.
	 */
	public Object addingService(ServiceReference reference) {
		if (Activator.DEBUG) {
			log.log(reference, LogService.LOG_DEBUG, "DriverLocatorTracker adding service"); //$NON-NLS-1$
		}

		return (context.getService(reference));
	}

	/**
	 * A service tracked by the ServiceTracker has been modified.
	 *
	 * <p>This method is called when a service being tracked
	 * by the ServiceTracker has had it properties modified.
	 *
	 * @param reference Reference to service that has been modified.
	 * @param service The service object for the modified service.
	 */
	public void modifiedService(ServiceReference reference, Object service) {
		//do nothing
	}

	/**
	 * A service tracked by the ServiceTracker is being removed.
	 *
	 * <p>This method is called after a service is no longer being tracked
	 * by the ServiceTracker.
	 *
	 * @param reference Reference to service that has been removed.
	 * @param service The service object for the removed service.
	 */
	public void removedService(ServiceReference reference, Object service) {
		if (Activator.DEBUG) {
			log.log(reference, LogService.LOG_DEBUG, "DriverLocatorTracker removing service"); //$NON-NLS-1$
		}

		context.ungetService(reference);
	}

	/**
	 * Call the DriverLocator services in an attempt to locate and
	 * install driver bundles to refine the device service.
	 *
	 * @param locators Array of DriverLocator objects
	 * @param drivers Dictionary of drivers with key=DRIVER_ID, value=Driver object
	 */
	public void loadDrivers(Dictionary properties, DriverTracker drivers) {
		if (Activator.DEBUG) {
			log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocatorTracker loadDrivers called"); //$NON-NLS-1$
		}

		ServiceReference[] references = getServiceReferences();

		if (references != null) {
			int size = references.length;

			for (int i = 0; i < size; i++) {
				ServiceReference locator = references[i];
				DriverLocator service = (DriverLocator) getService(locator);

				if (service != null) {
					if (Activator.DEBUG) {
						log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator findDrivers called"); //$NON-NLS-1$
					}

					try {
						String[] driver_ids = service.findDrivers(properties);

						if (Activator.DEBUG) {
							int count = (driver_ids == null) ? 0 : driver_ids.length;

							StringBuffer sb = new StringBuffer();

							sb.append('<');

							for (int k = 0; k < count; k++) {
								if (k > 0) {
									sb.append(',');
								}
								sb.append(driver_ids[k]);
							}

							sb.append('>');

							log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator findDrivers returned: " + sb); //$NON-NLS-1$
						}

						if (driver_ids != null) {
							int count = driver_ids.length;

							for (int j = 0; j < count; j++) {
								String driver_id = driver_ids[j];

								if (drivers.getDriver(driver_id) == null) {
									if (Activator.DEBUG) {
										log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver called for driver: " + driver_id); //$NON-NLS-1$
									}

									try {
										InputStream in = service.loadDriver(driver_id);

										if (Activator.DEBUG) {
											log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver returned: " + in); //$NON-NLS-1$
										}

										installDriverBundle(driver_id, in);
									} catch (Throwable t) {
										log.log(locator, LogService.LOG_ERROR, NLS.bind(DeviceMsg.DriverLocator_unable_to_load_driver, driver_id), t);
									}
								}
							}
						}
					} catch (Throwable t) {
						log.log(locator, LogService.LOG_ERROR, DeviceMsg.DriverLocator_error_calling_findDrivers, t);
					}
				}
			}
		}
	}

	/**
	 * Get an <code>InputStream</code> from which the driver bundle providing a driver with the giving ID can be installed.
	 *
	 * @param driver_id the ID of the driver that needs to be installed.
	 * bundle can be installed
	 */

	public void loadDriver(String driver_id, DriverTracker drivers) {
		if (Activator.DEBUG) {
			log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocatorTracker loadDriver called for driver: " + driver_id); //$NON-NLS-1$
		}

		if (drivers.getDriver(driver_id) == null) {
			ServiceReference[] references = getServiceReferences();

			if (references != null) {
				int size = references.length;

				for (int i = 0; i < size; i++) {
					ServiceReference locator = references[i];
					DriverLocator service = (DriverLocator) getService(locator);

					if (service != null) {
						if (Activator.DEBUG) {
							log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver called for driver: " + driver_id); //$NON-NLS-1$
						}

						try {
							InputStream in = service.loadDriver(driver_id);

							if (Activator.DEBUG) {
								log.log(locator, LogService.LOG_DEBUG, Thread.currentThread().getName() + ": DriverLocator loadDriver returned: " + in); //$NON-NLS-1$
							}

							if (in != null) {
								installDriverBundle(driver_id, in);

								break;
							}
						} catch (Throwable t) {
							log.log(locator, LogService.LOG_ERROR, NLS.bind(DeviceMsg.DriverLocator_unable_to_load_driver, driver_id), t);
						}
					}
				}
			}
		}
	}

	/**
	 * Install a Driver bundle.
	 *
	 * @param driver_id DRIVER_ID for new driver bundle.
	 * @param in InputStream to a new driver bundle.
	 */
	public void installDriverBundle(String driver_id, InputStream in) {
		if (Activator.DEBUG) {
			log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": installDriverBundle from InputStream: " + driver_id); //$NON-NLS-1$
		}

		if (in != null) {
			Bundle bundle = null;

			try {
				bundle = context.installBundle(driver_id, in);
				/* installBundle will close the InputStream */

				if (Activator.DEBUG) {
					log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle installed: " + driver_id); //$NON-NLS-1$
				}

				synchronized (bundles) {
					if (!bundles.contains(bundle)) {
						bundles.addElement(bundle);
					}
				}

				bundle.start();

				if (Activator.DEBUG) {
					log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle started: " + driver_id); //$NON-NLS-1$
				}
			} catch (BundleException e) {
				log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_install_or_start_driver_bundle, driver_id), e);

				if (bundle != null) {
					bundles.removeElement(bundle);

					try {
						bundle.uninstall();

						if (Activator.DEBUG) {
							log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle uninstalled: " + driver_id); //$NON-NLS-1$
						}
					} catch (BundleException ee) {
						log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_uninstall_driver_bundle_number, driver_id), ee);
					}

					bundle = null;
				}
			}
		}
	}

	/**
	 * Remove bundle from uninstall list.
	 *
	 * @param bundle bundle to remove from list.
	 */
	public void usingDriverBundle(Bundle bundle) {
		bundles.removeElement(bundle);
	}

	/**
	 * Uninstall the recently installed but unused driver bundles.
	 *
	 */
	public void uninstallDriverBundles() {
		int size;
		Bundle[] uninstall = null;

		synchronized (bundles) {
			size = bundles.size();

			if (size > 0) {
				uninstall = new Bundle[size];
				bundles.copyInto(uninstall);
			}
		}

		for (int i = 0; i < size; i++) {
			Bundle bundle = uninstall[i];

			if ((bundle.getState() & Bundle.UNINSTALLED) == 0) { /* if bundle not already uninstalled */
				try {
					bundle.uninstall();

					if (Activator.DEBUG) {
						log.log(LogService.LOG_DEBUG, Thread.currentThread().getName() + ": Driver bundle uninstalled"); //$NON-NLS-1$
					}
				} catch (BundleException ee) {
					log.log(LogService.LOG_ERROR, NLS.bind(DeviceMsg.Unable_to_uninstall_driver_bundle, ee));
				}
			}
		}

		bundles.removeAllElements();
	}

	public boolean isUninstallCandidate(Bundle bundle) {
		return bundles.contains(bundle);
	}
}
