package aQute.bnd.maven;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.*;
import java.util.jar.*;
import java.util.regex.*;

import aQute.bnd.header.*;
import aQute.bnd.maven.support.*;
import aQute.bnd.maven.support.Pom.Scope;
import aQute.bnd.osgi.*;
import aQute.bnd.osgi.Descriptors.PackageRef;
import aQute.lib.collections.*;
import aQute.lib.io.*;
import aQute.lib.settings.*;
import aQute.libg.command.*;

public class MavenCommand extends Processor {
	final Settings	settings	= new Settings();
	File			temp;

	public MavenCommand() {}

	public MavenCommand(Processor p) {
		super(p);
	}

	/**
	 * maven deploy [-url repo] [-passphrase passphrase] [-homedir homedir]
	 * [-keyname keyname] bundle ...
	 * 
	 * @param args
	 * @param i
	 * @throws Exception
	 */
	public void run(String args[], int i) throws Exception {
		temp = new File("maven-bundle");

		if (i >= args.length) {
			help();
			return;
		}

		while (i < args.length && args[i].startsWith("-")) {
			String option = args[i];
			trace("option " + option);
			if (option.equals("-temp"))
				temp = getFile(args[++i]);
			else {
				help();
				error("Invalid option " + option);
			}
			i++;
		}

		String cmd = args[i++];

		trace("temp dir " + temp);
		IO.delete(temp);
		if (!temp.exists() && !temp.mkdirs()) {
			throw new IOException("Could not create directory " + temp);
		}
		if (!temp.isDirectory())
			throw new IOException("Cannot create temp directory");

		if (cmd.equals("settings"))
			settings();
		else if (cmd.equals("help"))
			help();
		else if (cmd.equals("bundle"))
			bundle(args, i);
		else if (cmd.equals("view"))
			view(args, i);
		else
			error("No such command %s, type help", cmd);
	}

	private void help() {
		System.err.printf("Usage:%n");
		System.err
				.printf("  maven %n" //
						+ "  [-temp <dir>]            use as temp directory%n" //
						+ "  settings                 show maven settings%n" //
						+ "  bundle                   turn a bundle into a maven bundle%n" //
						+ "    [-properties <file>]   provide properties, properties starting with javadoc are options for javadoc, like javadoc-tag=...%n"
						+ "    [-javadoc <file|url>]  where to find the javadoc (zip/dir), otherwise generated%n" //
						+ "    [-source <file|url>]   where to find the source (zip/dir), otherwise from OSGI-OPT/src%n" //
						+ "    [-scm <url>]           required scm in pom, otherwise from Bundle-SCM%n" //
						+ "    [-url <url>]           required project url in pom%n" //
						+ "    [-bsn bsn]             overrides bsn%n" //
						+ "    [-version <version>]   overrides version%n" //
						+ "    [-developer <email>]   developer email%n" //
						+ "    [-nodelete]            do not delete temp files%n" //
						+ "    [-passphrase <gpgp passphrase>] signer password%n"//
						+ "        <file|url>%n");
	}

	/**
	 * Show the maven settings
	 * 
	 * @throws FileNotFoundException
	 * @throws Exception
	 */
	private void settings() throws FileNotFoundException, Exception {
		File userHome = new File(System.getProperty("user.home"));
		File m2 = new File(userHome, ".m2");
		if (!m2.isDirectory()) {
			error("There is no m2 directory at %s", userHome);
			return;
		}
		File settings = new File(m2, "settings.xml");
		if (!settings.isFile()) {
			error("There is no settings file at '%s'", settings.getAbsolutePath());
			return;
		}
		LineCollection lc = new LineCollection(IO.reader(settings));
		while (lc.hasNext()) {
			System.err.println(lc.next());
		}
	}

	/**
	 * Create a maven bundle.
	 * 
	 * @param args
	 * @param i
	 * @throws Exception
	 */
	private void bundle(String args[], int i) throws Exception {
		List<String> developers = new ArrayList<String>();
		Properties properties = new Properties();

		String scm = null;
		String passphrase = null;
		String javadoc = null;
		String source = null;
		String output = "bundle.jar";
		String url = null;
		String artifact = null;
		String group = null;
		String version = null;
		boolean nodelete = false;

		while (i < args.length && args[i].startsWith("-")) {
			String option = args[i++];
			trace("bundle option %s", option);
			if (option.equals("-scm"))
				scm = args[i++];
			else if (option.equals("-group"))
				group = args[i++];
			else if (option.equals("-artifact"))
				artifact = args[i++];
			else if (option.equals("-version"))
				version = args[i++];
			else if (option.equals("-developer"))
				developers.add(args[i++]);
			else if (option.equals("-passphrase")) {
				passphrase = args[i++];
			} else if (option.equals("-url")) {
				url = args[i++];
			} else if (option.equals("-javadoc"))
				javadoc = args[i++];
			else if (option.equals("-source"))
				source = args[i++];
			else if (option.equals("-output"))
				output = args[i++];
			else if (option.equals("-nodelete"))
				nodelete = true;
			else if (option.startsWith("-properties")) {
				InputStream in = null;
				try {
					in = new FileInputStream(args[i++]);
					properties.load(in);
				}
				catch (Exception e) {}
				finally {
					if (in != null) {
						in.close();
					}
				}
			}
		}

		if (developers.isEmpty()) {
			String email = settings.remove("email");
			if (email == null)
				error("No developer email set, you can set global default email with: bnd global email Peter.Kriens@aQute.biz");
			else
				developers.add(email);
		}

		if (i == args.length) {
			error("too few arguments, no bundle specified");
			return;
		}

		if (i != args.length - 1) {
			error("too many arguments, only one bundle allowed");
			return;
		}

		String input = args[i++];

		Jar binaryJar = getJarFromFileOrURL(input);
		trace("got %s", binaryJar);
		if (binaryJar == null) {
			error("JAR does not exist: %s", input);
			return;
		}

		File original = getFile(temp, "original");
		if (!original.exists() && !original.mkdirs()) {
			throw new IOException("Could not create directory " + original);
		}
		binaryJar.expand(original);
		binaryJar.calcChecksums(null);

		Manifest manifest = binaryJar.getManifest();
		trace("got manifest");

		PomFromManifest pom = new PomFromManifest(manifest);

		if (scm != null)
			pom.setSCM(scm);
		if (url != null)
			pom.setURL(url);
		if (artifact != null)
			pom.setArtifact(artifact);
		if (artifact != null)
			pom.setGroup(group);
		if (version != null)
			pom.setVersion(version);
		trace(url);
		for (String d : developers)
			pom.addDeveloper(d);

		Set<String> exports = OSGiHeader.parseHeader(manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE))
				.keySet();

		Jar sourceJar;
		if (source == null) {
			trace("Splitting source code");
			sourceJar = new Jar("source");
			for (Map.Entry<String,Resource> entry : binaryJar.getResources().entrySet()) {
				if (entry.getKey().startsWith("OSGI-OPT/src")) {
					sourceJar.putResource(entry.getKey().substring("OSGI-OPT/src/".length()), entry.getValue());
				}
			}
			copyInfo(binaryJar, sourceJar, "source");
		} else {
			sourceJar = getJarFromFileOrURL(source);
		}
		sourceJar.calcChecksums(null);

		Jar javadocJar;
		if (javadoc == null) {
			trace("creating javadoc because -javadoc not used");
			javadocJar = javadoc(getFile(original, "OSGI-OPT/src"), exports, manifest, properties);
			if (javadocJar == null) {
				error("Cannot find source code in OSGI-OPT/src to generate Javadoc");
				return;
			}
			copyInfo(binaryJar, javadocJar, "javadoc");
		} else {
			trace("Loading javadoc externally %s", javadoc);
			javadocJar = getJarFromFileOrURL(javadoc);
		}
		javadocJar.calcChecksums(null);

		addClose(binaryJar);
		addClose(sourceJar);
		addClose(javadocJar);

		trace("creating bundle dir");
		File bundle = new File(temp, "bundle");
		if (!bundle.exists() && !bundle.mkdirs()) {
			throw new IOException("Could not create directory " + bundle);
		}

		String prefix = pom.getArtifactId() + "-" + pom.getVersion();
		File binaryFile = new File(bundle, prefix + ".jar");
		File sourceFile = new File(bundle, prefix + "-sources.jar");
		File javadocFile = new File(bundle, prefix + "-javadoc.jar");
		File pomFile = new File(bundle, "pom.xml").getAbsoluteFile();
		trace("creating output files %s, %s,%s, and %s", binaryFile, sourceFile, javadocFile, pomFile);

		IO.copy(pom.openInputStream(), pomFile);
		trace("copied pom");

		trace("writing binary %s", binaryFile);
		binaryJar.write(binaryFile);

		trace("writing source %s", sourceFile);
		sourceJar.write(sourceFile);

		trace("writing javadoc %s", javadocFile);
		javadocJar.write(javadocFile);

		sign(binaryFile, passphrase);
		sign(sourceFile, passphrase);
		sign(javadocFile, passphrase);
		sign(pomFile, passphrase);

		trace("create bundle");
		Jar bundleJar = new Jar(bundle);
		addClose(bundleJar);
		File outputFile = getFile(output);
		bundleJar.write(outputFile);
		trace("created bundle %s", outputFile);

		binaryJar.close();
		sourceJar.close();
		javadocJar.close();
		bundleJar.close();
		if (!nodelete)
			IO.delete(temp);
	}

	private void copyInfo(Jar source, Jar dest, String type) throws Exception {
		source.ensureManifest();
		dest.ensureManifest();
		copyInfoResource(source, dest, "LICENSE");
		copyInfoResource(source, dest, "LICENSE.html");
		copyInfoResource(source, dest, "about.html");

		Manifest sm = source.getManifest();
		Manifest dm = dest.getManifest();
		copyInfoHeader(sm, dm, "Bundle-Description", "");
		copyInfoHeader(sm, dm, "Bundle-Vendor", "");
		copyInfoHeader(sm, dm, "Bundle-Copyright", "");
		copyInfoHeader(sm, dm, "Bundle-DocURL", "");
		copyInfoHeader(sm, dm, "Bundle-License", "");
		copyInfoHeader(sm, dm, "Bundle-Name", " " + type);
		copyInfoHeader(sm, dm, "Bundle-SymbolicName", "." + type);
		copyInfoHeader(sm, dm, "Bundle-Version", "");
	}

	private void copyInfoHeader(Manifest sm, Manifest dm, String key, String value) {
		String v = sm.getMainAttributes().getValue(key);
		if (v == null) {
			trace("no source for " + key);
			return;
		}

		if (dm.getMainAttributes().getValue(key) != null) {
			trace("already have " + key);
			return;
		}

		dm.getMainAttributes().putValue(key, v + value);
	}

	private void copyInfoResource(Jar source, Jar dest, String type) {
		if (source.getResources().containsKey(type) && !dest.getResources().containsKey(type))
			dest.putResource(type, source.getResource(type));
	}

	/**
	 * @return
	 * @throws IOException
	 * @throws MalformedURLException
	 */
	protected Jar getJarFromFileOrURL(String spec) throws IOException, MalformedURLException {
		Jar jar;
		File jarFile = getFile(spec);
		if (jarFile.exists()) {
			jar = new Jar(jarFile);
		} else {
			URL url = new URL(spec);
			InputStream in = url.openStream();
			try {
				jar = new Jar(url.getFile(), in);
			}
			finally {
				in.close();
			}
		}
		addClose(jar);
		return jar;
	}

	private void sign(File file, String passphrase) throws Exception {
		trace("signing %s", file);
		File asc = new File(file.getParentFile(), file.getName() + ".asc");
		asc.delete();

		Command command = new Command();
		command.setTrace();

		command.add(getProperty("gpgp", "gpg"));
		if (passphrase != null)
			command.add("--passphrase", passphrase);
		command.add("-ab", "--sign"); // not the -b!!
		command.add(file.getAbsolutePath());
		System.err.println(command);
		StringBuilder stdout = new StringBuilder();
		StringBuilder stderr = new StringBuilder();
		int result = command.execute(stdout, stderr);
		if (result != 0) {
			error("gpg signing %s failed because %s", file, "" + stdout + stderr);
		}
	}

	private Jar javadoc(File source, Set<String> exports, Manifest m, Properties p) throws Exception {
		File tmp = new File(temp, "javadoc");
		if (!tmp.exists() && !tmp.mkdirs()) {
			throw new IOException("Could not create directory " + tmp);
		}

		Command command = new Command();
		command.add(getProperty("javadoc", "javadoc"));
		command.add("-quiet");
		command.add("-protected");
		// command.add("-classpath");
		// command.add(binary.getAbsolutePath());
		command.add("-d");
		command.add(tmp.getAbsolutePath());
		command.add("-charset");
		command.add("UTF-8");
		command.add("-sourcepath");
		command.add(source.getAbsolutePath());

		Attributes attr = m.getMainAttributes();
		Properties pp = new Properties(p);
		set(pp, "-doctitle", description(attr));
		set(pp, "-header", description(attr));
		set(pp, "-windowtitle", name(attr));
		set(pp, "-bottom", copyright(attr));
		set(pp, "-footer", license(attr));

		command.add("-tag");
		command.add("Immutable:t:Immutable");
		command.add("-tag");
		command.add("ThreadSafe:t:ThreadSafe");
		command.add("-tag");
		command.add("NotThreadSafe:t:NotThreadSafe");
		command.add("-tag");
		command.add("GuardedBy:mf:Guarded By:");
		command.add("-tag");
		command.add("security:m:Required Permissions");
		command.add("-tag");
		command.add("noimplement:t:Consumers of this API must not implement this interface");

		for (Enumeration< ? > e = pp.propertyNames(); e.hasMoreElements();) {
			String key = (String) e.nextElement();
			String value = pp.getProperty(key);

			if (key.startsWith("javadoc")) {
				key = key.substring("javadoc".length());
				removeDuplicateMarker(key);
				command.add(key);
				command.add(value);
			}
		}
		for (String packageName : exports) {
			command.add(packageName);
		}

		StringBuilder out = new StringBuilder();
		StringBuilder err = new StringBuilder();

		System.err.println(command);

		int result = command.execute(out, err);
		if (result != 0) {
			warning("Error during execution of javadoc command: %s\n******************\n%s", out, err);
		}
		Jar jar = new Jar(tmp);
		addClose(jar);
		return jar;
	}

	/**
	 * Generate a license string
	 * 
	 * @param attr
	 * @return
	 */
	private String license(Attributes attr) {
		Parameters map = Processor.parseHeader(attr.getValue(Constants.BUNDLE_LICENSE), null);
		if (map.isEmpty())
			return null;

		StringBuilder sb = new StringBuilder();
		String sep = "Licensed under ";
		for (Entry<String,Attrs> entry : map.entrySet()) {
			sb.append(sep);
			String key = entry.getKey();
			String link = entry.getValue().get("link");
			String description = entry.getValue().get("description");

			if (description == null)
				description = key;

			if (link != null) {
				sb.append("<a href='");
				sb.append(link);
				sb.append("'>");
			}
			sb.append(description);
			if (link != null) {
				sb.append("</a>");
			}
			sep = ",<br/>";
		}

		return sb.toString();
	}

	/**
	 * Generate the copyright statement.
	 * 
	 * @param attr
	 * @return
	 */
	private String copyright(Attributes attr) {
		return attr.getValue(Constants.BUNDLE_COPYRIGHT);
	}

	private String name(Attributes attr) {
		String name = attr.getValue(Constants.BUNDLE_NAME);
		if (name == null)
			name = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
		return name;
	}

	private String description(Attributes attr) {
		String descr = attr.getValue(Constants.BUNDLE_DESCRIPTION);
		if (descr == null)
			descr = attr.getValue(Constants.BUNDLE_NAME);
		if (descr == null)
			descr = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
		return descr;
	}

	private void set(Properties pp, String option, String defaultValue) {
		String key = "javadoc" + option;
		String existingValue = pp.getProperty(key);
		if (existingValue != null)
			return;

		pp.setProperty(key, defaultValue);
	}

	/**
	 * View - Show the dependency details of an artifact
	 */

	static Executor	executor				= Executors.newCachedThreadPool();
	static Pattern	GROUP_ARTIFACT_VERSION	= Pattern.compile("([^+]+)\\+([^+]+)\\+([^+]+)");

	void view(String args[], int i) throws Exception {
		Maven maven = new Maven(executor);
		OutputStream out = System.err;

		List<URI> urls = new ArrayList<URI>();

		while (i < args.length && args[i].startsWith("-")) {
			if ("-r".equals(args[i])) {
				URI uri = new URI(args[++i]);
				urls.add(uri);
				System.err.println("URI for repo " + uri);
			} else if ("-o".equals(args[i])) {
				out = new FileOutputStream(args[++i]);
			} else
				throw new IllegalArgumentException("Unknown option: " + args[i]);

			i++;
		}

		URI[] urls2 = urls.toArray(new URI[urls.size()]);
		PrintWriter pw = IO.writer(out);

		while (i < args.length) {
			String ref = args[i++];
			pw.println("Ref " + ref);

			Matcher matcher = GROUP_ARTIFACT_VERSION.matcher(ref);
			if (matcher.matches()) {

				String group = matcher.group(1);
				String artifact = matcher.group(2);
				String version = matcher.group(3);
				CachedPom pom = maven.getPom(group, artifact, version, urls2);

				Builder a = new Builder();
				a.setProperty("Private-Package", "*");
				Set<Pom> dependencies = pom.getDependencies(Scope.compile, urls2);
				for (Pom dep : dependencies) {
					System.err.printf("%20s %-20s %10s%n", dep.getGroupId(), dep.getArtifactId(), dep.getVersion());
					a.addClasspath(dep.getArtifact());
				}
				pw.println(a.getClasspath());
				a.build();

				TreeSet<PackageRef> sorted = new TreeSet<PackageRef>(a.getImports().keySet());
				for (PackageRef p : sorted) {
					pw.printf("%-40s\n", p);
				}
				// for ( Map.Entry<String, Set<String>> entry :
				// a.getUses().entrySet()) {
				// String from = entry.getKey();
				// for ( String uses : entry.getValue()) {
				// System.err.printf("%40s %s\n", from, uses);
				// from = "";
				// }
				// }
				a.close();
			} else
				System.err.println("Wrong, must look like group+artifact+version, is " + ref);

		}
	}

}
