/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.tests.verifier;

import java.io.*;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.internal.adaptor.EclipseAdaptorMsg;
import org.eclipse.core.runtime.internal.adaptor.MessageHelper;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.service.packageadmin.PackageAdmin;

/**
 * Application which verifies an install.
 * 
 * @since 1.0
 */
public class VerifierApplication implements IApplication {

	private static final File DEFAULT_PROPERTIES_FILE = new File("verifier.properties"); //$NON-NLS-1$
	private static final String ARG_PROPERTIES = "-verifier.properties"; //$NON-NLS-1$
	private IProvisioningAgent agent;
	private Properties properties = null;
	private List ignoreResolved = null;

	/*
	 * Create and return an error status with the given message.
	 */
	private static IStatus createError(String message) {
		return new Status(IStatus.ERROR, Activator.PLUGIN_ID, message);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
	 */
	public Object start(IApplicationContext context) throws Exception {
		String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
		processArguments(args);

		agent = (IProvisioningAgent) ServiceHelper.getService(Activator.getBundleContext(), IProvisioningAgent.SERVICE_NAME);

		IStatus result = verify();
		if (!result.isOK()) {
			//			PrintWriter out = new PrintWriter(new FileWriter(new File("c:/tmp/dropins-debug.txt")));
			PrintWriter out = new PrintWriter(new OutputStreamWriter(System.err));
			out.println("Error from dropin verifier application: " + result.getMessage()); //$NON-NLS-1$
			Throwable t = result.getException();
			if (t != null)
				t.printStackTrace(out);
			out.close();
			LogHelper.log(result);
		}
		return result.isOK() ? IApplication.EXIT_OK : new Integer(13);
	}

	/*
	 * Go through the command-line args and pull out interesting ones
	 * for later consumption.
	 */
	private void processArguments(String[] args) {
		if (args == null)
			return;

		for (int i = 1; i < args.length; i++) {
			if (ARG_PROPERTIES.equals(args[i - 1])) {
				String filename = args[i];
				if (filename.startsWith("-")) //$NON-NLS-1$
					continue;
				try {
					properties = readProperties(new File(filename));
				} catch (IOException e) {
					// TODO
					e.printStackTrace();
					// fall through to load default
				}
				continue;
			}
		}

		// problems loading properties file or none specified so look for a default
		if (properties == null) {
			try {
				if (DEFAULT_PROPERTIES_FILE.exists())
					properties = readProperties(DEFAULT_PROPERTIES_FILE);
			} catch (IOException e) {
				// TODO 
				e.printStackTrace();
			}
		}
		if (properties == null)
			properties = new Properties();
	}

	/*
	 * Read and return a properties file at the given location.
	 */
	private Properties readProperties(File file) throws IOException {
		Properties result = new Properties();
		InputStream input = null;
		try {
			input = new BufferedInputStream(new FileInputStream(file));
			result.load(input);
			return result;
		} finally {
			if (input != null)
				try {
					input.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.equinox.app.IApplication#stop()
	 */
	public void stop() {
		// nothing to do
	}

	/*
	 * Return a boolean value indicating whether or not the bundle with the given symbolic name
	 * should be considered when looking at bundles which are not resolved in the system.
	 * TODO the call to this method was removed. we should add it back
	 */
	protected boolean shouldCheckResolved(String bundle) {
		if (ignoreResolved == null) {
			ignoreResolved = new ArrayList();
			String list = properties.getProperty("ignore.unresolved");
			if (list == null)
				return true;
			for (StringTokenizer tokenizer = new StringTokenizer(list, ","); tokenizer.hasMoreTokens();)
				ignoreResolved.add(tokenizer.nextToken().trim());
		}
		for (Iterator iter = ignoreResolved.iterator(); iter.hasNext();) {
			if (bundle.equals(iter.next()))
				return false;
		}
		return true;
	}

	private List getAllBundles() {
		PlatformAdmin platformAdmin = (PlatformAdmin) ServiceHelper.getService(Activator.getBundleContext(), PlatformAdmin.class.getName());
		PackageAdmin packageAdmin = (PackageAdmin) ServiceHelper.getService(Activator.getBundleContext(), PackageAdmin.class.getName());
		State state = platformAdmin.getState(false);
		List result = new ArrayList();

		BundleDescription[] bundles = state.getBundles();
		for (int i = 0; i < bundles.length; i++) {
			BundleDescription bundle = bundles[i];
			Bundle[] versions = packageAdmin.getBundles(bundle.getSymbolicName(), bundle.getVersion().toString());
			for (int j = 0; j < versions.length; j++)
				result.add(versions[j]);
		}
		return result;
	}

	/*
	 * Check to ensure all of the bundles in the system are resolved.
	 * 
	 * Copied and modified from EclipseStarter#logUnresolvedBundles.
	 * This method prints out all the reasons while asking the resolver directly
	 * will only print out the first reason.
	 */
	private IStatus checkResolved() {
		List allProblems = new ArrayList();
		PlatformAdmin platformAdmin = (PlatformAdmin) ServiceHelper.getService(Activator.getBundleContext(), PlatformAdmin.class.getName());
		State state = platformAdmin.getState(false);
		StateHelper stateHelper = platformAdmin.getStateHelper();

		// first lets look for missing leaf constraints (bug 114120)
		VersionConstraint[] leafConstraints = stateHelper.getUnsatisfiedLeaves(state.getBundles());
		// hash the missing leaf constraints by the declaring bundles
		Map missing = new HashMap();
		for (int i = 0; i < leafConstraints.length; i++) {
			// only include non-optional and non-dynamic constraint leafs
			if (leafConstraints[i] instanceof BundleSpecification && ((BundleSpecification) leafConstraints[i]).isOptional())
				continue;
			if (leafConstraints[i] instanceof ImportPackageSpecification) {
				if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE)))
					continue;
				if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(((ImportPackageSpecification) leafConstraints[i]).getDirective(Constants.RESOLUTION_DIRECTIVE)))
					continue;
			}
			BundleDescription bundleDesc = leafConstraints[i].getBundle();
			ArrayList constraints = (ArrayList) missing.get(bundleDesc);
			if (constraints == null) {
				constraints = new ArrayList();
				missing.put(bundleDesc, constraints);
			}
			constraints.add(leafConstraints[i]);
		}

		// found some bundles with missing leaf constraints; log them first 
		if (missing.size() > 0) {
			int rootIndex = 0;
			for (Iterator iter = missing.keySet().iterator(); iter.hasNext(); rootIndex++) {
				BundleDescription description = (BundleDescription) iter.next();
				String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, description.getLocation());
				ArrayList constraints = (ArrayList) missing.get(description);
				for (Iterator inner = constraints.iterator(); inner.hasNext();) {
					String message = generalMessage + " Reason: " + MessageHelper.getResolutionFailureMessage((VersionConstraint) inner.next()); //$NON-NLS-1$
					allProblems.add(createError(message));
				}
			}
		}

		// There may be some bundles unresolved for other reasons, causing the system to be unresolved
		// log all unresolved constraints now
		List allBundles = getAllBundles();
		for (Iterator i = allBundles.iterator(); i.hasNext();) {
			Bundle bundle = (Bundle) i.next();
			if (bundle.getState() == Bundle.INSTALLED) {
				String generalMessage = NLS.bind(EclipseAdaptorMsg.ECLIPSE_STARTUP_ERROR_BUNDLE_NOT_RESOLVED, bundle);
				BundleDescription description = state.getBundle(bundle.getBundleId());
				// for some reason, the state does not know about that bundle
				if (description == null)
					continue;
				VersionConstraint[] unsatisfied = stateHelper.getUnsatisfiedConstraints(description);
				if (unsatisfied.length > 0) {
					// the bundle wasn't resolved due to some of its constraints were unsatisfiable
					for (int j = 0; j < unsatisfied.length; j++)
						allProblems.add(createError(generalMessage + " Reason: " + MessageHelper.getResolutionFailureMessage(unsatisfied[j]))); //$NON-NLS-1$
				} else {
					ResolverError[] resolverErrors = state.getResolverErrors(description);
					for (int j = 0; j < resolverErrors.length; j++) {
						if (shouldAdd(resolverErrors[j])) {
							allProblems.add(createError(generalMessage + " Reason: " + resolverErrors[j].toString())); //$NON-NLS-1$
						}
					}
				}
			}
		}
		MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, "Problems checking resolved bundles.", null); //$NON-NLS-1$
		for (Iterator iter = allProblems.iterator(); iter.hasNext();)
			result.add((IStatus) iter.next());
		return result;
	}

	/*
	 * Return a boolean value indicating whether or not the given resolver error should be 
	 * added to our results.
	 */
	private boolean shouldAdd(ResolverError error) {
		// ignore EE problems? default value is true
		String prop = properties.getProperty("ignore.ee"); //$NON-NLS-1$
		boolean ignoreEE = prop == null || Boolean.valueOf(prop).booleanValue();
		if (ResolverError.MISSING_EXECUTION_ENVIRONMENT == error.getType() && ignoreEE)
			return false;
		return true;
	}

	/*
	 * Ensure we have a profile registry and can access the SELF profile.
	 */
	private IStatus checkProfileRegistry() {
		IProfileRegistry registry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
		if (registry == null)
			return createError("Profile registry service not available."); //$NON-NLS-1$
		IProfile profile = registry.getProfile(IProfileRegistry.SELF);
		if (profile == null)
			return createError("SELF profile not available in profile registry."); //$NON-NLS-1$
		IQueryResult results = profile.query(QueryUtil.createIUQuery(Activator.PLUGIN_ID), null);
		if (results.isEmpty())
			return createError(NLS.bind("IU for {0} not found in SELF profile.", Activator.PLUGIN_ID)); //$NON-NLS-1$
		return Status.OK_STATUS;
	}

	/*
	 * Perform all of the verification checks.
	 */
	public IStatus verify() {
		String message = "Problems occurred during verification."; //$NON-NLS-1$
		MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, message, null);

		// ensure all the bundles are resolved
		IStatus temp = checkResolved();
		if (!temp.isOK())
			result.merge(temp);

		// ensure we have a profile registry
		temp = checkProfileRegistry();
		if (!temp.isOK())
			result.merge(temp);

		return result;
	}

}
