/*******************************************************************************
 * 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.europa.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.europa.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;

	}
}
