/*******************************************************************************
 * Copyright (c) 2006 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:
 *      Pascal Rapicault, IBM - Initial implementation
 *      David Williams, IBM, - added 
 *          'conservative' directive
 *          'workpaceRoot' directive
 *          maintained some other attributes in pre-req'd bundles
 *          made output "ready to paste", if desired. 
 *      
 *******************************************************************************/
package org.eclipse.callisto.tools.versionchecker;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;

import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
import org.eclipse.osgi.service.resolver.VersionRange;
import org.osgi.framework.Version;

/**
 * A simple, unsupported, little-tested utility to help convert from using
 * unconstrained pre-req'd bundles, to ones constrained to be within a certain
 * range.
 * 
 * For example, if a plugin's manifest.mf file specifies
 * 
 * <p>
 * <code>Require-Bundle: org.eclipse.core.runtime</code>
 * </p>
 * <p>
 * this utility will write
 * </p>
 * <p>
 * <code>Require-Bundle: org.eclipse.core.runtime;bundle-version=&quot;[3.2.0,4.0.0)&quot;</code>
 * </p>
 * <p>
 * or
 * </p>
 * <p>
 * <code>Require-Bundle: org.eclipse.core.runtime;bundle-version=&quot;[3.2.0,3.3.0)&quot;</code>
 * </p>
 * <p>
 * if <i>-conservative</i> is specified. In all case the lower bound is
 * determined by the version found as this utility actually runs.
 * 
 * </pre>
 * 
 * <p>
 * Directives:
 * </p>
 * <p>
 * -filter "some regx expression"
 * </p>
 * <p>
 * Will write/check manifest only for those plugins matching regx expression.
 * </p>
 * <p>
 * -conservative
 * </p>
 * <p>
 * Will increment 'minor' code, instead of 'major' code in upper bound of the
 * range. This is required for those using another plugin's internal (non-API)
 * methods, and recommended if you do not know for sure you are using
 * API-only. The default is not-conservative, which increments the major
 * field.
 * </p>
 * <p>
 * -workspaceRoot "absolute file system path name to workspace"
 * </p>
 * <p>
 * If specified, the manifest.mf files found in the workspace will be
 * re-written with the results of this tool. Note. The workspace must "match"
 * the runtime the tool is running in, for this to make any sense. The default
 * is to simply write the recommended "Require-Bundle:" section the console
 * log.
 * </p>
 * <p>
 * Note: re-export visibility and optional resolution are maintained "as is"
 * in output (but other pre-req settings (e.g. vendor?) may be lost. The
 * intent is to provide "ready for pasting" content, if its happens to work
 * well for your cases.
 * </p>
 * <p>
 * Example invocation:
 * </p>
 * <p>
 * 
 * <pre>
 * 
 * java -jar startup.jar -clean -application
 * org.eclipse.callisto.tools.versionchecker.dependencyChecker
 * 
 * </pre>
 * 
 * </p>
 * 
 * <p>
 * Example output:
 * </p>
 * 
 * <pre>
 * 
 * bundle org.eclipse.wst.xml.core Require-Bundle:
 * org.eclipse.core.runtime;bundle-version=&quot;[3.2.0,3.3.0)&quot;,
 * org.eclipse.core.resources;bundle-version=&quot;[3.2.0,3.3.0)&quot;,
 * org.eclipse.wst.common.uriresolver;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * org.eclipse.wst.sse.core;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * org.eclipse.text;bundle-version=&quot;[3.2.0,3.3.0)&quot;,
 * org.eclipse.jem.util;resolution:=optional;bundle-version=&quot;[1.2.0,1.3.0)&quot;,
 * org.eclipse.wst.validation;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * org.eclipse.emf.ecore.edit;resolution:=optional;bundle-version=&quot;[2.2.0,2.3.0)&quot;,
 * org.eclipse.wst.common.emf;resolution:=optional;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * org.eclipse.emf.ecore.xmi;resolution:=optional;bundle-version=&quot;[2.2.0,2.3.0)&quot;,
 * org.eclipse.wst.common.emfworkbench.integration;resolution:=optional;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * org.eclipse.wst.common.core;bundle-version=&quot;[1.1.0,1.2.0)&quot;,
 * com.ibm.icu;bundle-version=&quot;[3.4.4,3.5.0)&quot;,
 * org.apache.xerces;visibility:=reexport;bundle-version=&quot;[2.8.0,2.9.0)&quot;
 * 
 * </pre>
 */
public class DependencyChecker implements IPlatformRunnable {

	private static final String CONSERVATIVE_DIRECTIVE = "-conservative";
	private static final String FILTER_DIRECTIVE = "-filter";
	private static final String WORKSPACEROOT_DIRECTIVE = "-workspaceRoot";

	private static final String REQUIRE_BUNDLE = "Require-Bundle:";
	private static final String EOL = System.getProperty("line.separator");
	private boolean conservative = false;
	private String workspaceroot;



	public DependencyChecker() {
	}

	public Object run(Object o) throws Exception {
		String args[] = Platform.getApplicationArgs();
		String filter = null;
		for (int nArgs = 0; nArgs < args.length; nArgs++) {
			if (args[nArgs].equals(FILTER_DIRECTIVE) && (nArgs + 1 < args.length))
				filter = args[nArgs + 1];
			else if (args[nArgs].equals(CONSERVATIVE_DIRECTIVE)) {
				conservative = true;
			}
			else if (args[nArgs].equals(WORKSPACEROOT_DIRECTIVE) && (nArgs + 1 < args.length))
				workspaceroot = args[nArgs + 1];

		}

		BundleDescription bundles[] = Platform.getPlatformAdmin().getState().getBundles();
		for (int i = 0; i < bundles.length; i++) {
			String bundleName = bundles[i].getSymbolicName();
			if ((filter == null) || bundleName.matches(filter)) {
				BundleSpecification req[] = bundles[i].getRequiredBundles();
				ArrayList bundleSpecStrings = new ArrayList();
				for (int j = 0; j < req.length; j++) {

					BundleSpecification currentBundle = req[j];
					VersionRange specifiedRange = currentBundle.getVersionRange();
					if (specifiedRange == VersionRange.emptyRange) {

						BundleDescription required = Platform.getPlatformAdmin().getState().getBundle(currentBundle.getName(), null);
						if (required != null) {
							Version reqVersion = required.getVersion();
							Version minVersion = new Version(reqVersion.getMajor(), reqVersion.getMinor(), reqVersion.getMicro());
							Version maxVersion = null;
							if (conservative) {
								maxVersion = new Version(minVersion.getMajor(), minVersion.getMinor() + 1, 0);
							}
							else {
								maxVersion = new Version(minVersion.getMajor() + 1, 0, 0);

							}

							String name = currentBundle.getName();

							String exported = "";
							if (currentBundle.isExported()) {
								exported = ";visibility:=reexport";
							}

							String optional = "";
							if (currentBundle.isOptional()) {
								exported = ";resolution:=optional";
							}

							String requiredRange = ";bundle-version=\"" + new VersionRange(minVersion, true, maxVersion, false) + "\"";

							String spec = new String(" " + name + exported + optional + requiredRange);

							bundleSpecStrings.add(spec);
						}
					}
				}

				// print
				if (bundleSpecStrings.size() > 0) {
					// header
					System.out.println();
					System.out.println("bundle " + bundleName);

					StringBuffer sb = formStringBuffer(bundleSpecStrings);

					System.out.println(sb);

					if (workspaceroot != null) {
						rewriteManifest(bundleName, sb);
					}

				}
			}
		}

		return IPlatformRunnable.EXIT_OK;
	}

	private void rewriteManifest(String bundleName, StringBuffer sb) throws IOException {

		try {
			Reader reader = new FileReader(workspaceroot + bundleName + "/META-INF/MANIFEST.MF");

			BufferedReader bufferedReader = new BufferedReader(reader);
			ArrayList initialLines = new ArrayList();
			ArrayList finalLines = new ArrayList();
			String inline = null;
			inline = bufferedReader.readLine();
			while ((inline != null) && (!(inline.startsWith(REQUIRE_BUNDLE)))) {
				initialLines.add(new String(inline));
				inline = bufferedReader.readLine();
			}

			if (inline != null) {
				inline = bufferedReader.readLine();
				while (((inline != null) && (inline.startsWith(" ")))) {
					inline = bufferedReader.readLine();
				}
			}

			while (inline != null) {
				finalLines.add(new String(inline));
				inline = bufferedReader.readLine();
			}
			bufferedReader.close();

			Writer writer = new FileWriter(workspaceroot + bundleName + "/META-INF/MANIFEST.MF");
			BufferedWriter bufferedWriter = new BufferedWriter(writer);
			for (int lines = 0; lines < initialLines.size(); lines++) {
				bufferedWriter.write(initialLines.get(lines) + EOL);
			}
			bufferedWriter.write(sb.toString());
			for (int lines = 0; lines < finalLines.size(); lines++) {
				bufferedWriter.write(finalLines.get(lines) + EOL);
			}
			bufferedWriter.close();
		}
		catch (FileNotFoundException e) {
			// if no manifest file, ignore, there's nothing to re-write
		}
	}

	private StringBuffer formStringBuffer(ArrayList bundleSpecStrings) {
		StringBuffer sb = new StringBuffer();

		// spec section (note, print only, no EOL, no space)
		sb.append(REQUIRE_BUNDLE);

		for (int k = 0; k < bundleSpecStrings.size(); k++) {
			sb.append(bundleSpecStrings.get(k));
			String COMMA = "";
			if (k < bundleSpecStrings.size() - 1) {
				COMMA = ",";
			}
			sb.append(COMMA + EOL);
		}

		return sb;

	}
}
