/*******************************************************************************
 * Copyright (C) 2013 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.maven.plugins;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.DefaultDependencyResolutionRequest;
import org.apache.maven.project.DependencyResolutionException;
import org.apache.maven.project.DependencyResolutionResult;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectDependenciesResolver;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.util.filter.ScopeDependencyFilter;

import uk.org.taverna.commons.profile.xml.jaxb.BundleInfo;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.OSGiHeader;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Constants;
import aQute.bnd.version.Version;
import aQute.bnd.version.VersionRange;

/**
 * @author David Withers
 */
public class MavenOsgiUtils {

	private final MavenProject project;
	private final RepositorySystemSession repositorySystemSession;
	private final ProjectDependenciesResolver projectDependenciesResolver;
	private final Log log;

	private Set<String> javaPackages;
	private Set<String> systemPackages;

	public MavenOsgiUtils(MavenProject project, RepositorySystemSession repositorySystemSession,
			ProjectDependenciesResolver projectDependenciesResolver, Log log) {
		this(project, repositorySystemSession, projectDependenciesResolver, new HashSet<String>(),
				log);
	}

	public MavenOsgiUtils(MavenProject project, RepositorySystemSession repositorySystemSession,
			ProjectDependenciesResolver projectDependenciesResolver, Set<String> systemPackages,
			Log log) {
		this.project = project;
		this.repositorySystemSession = repositorySystemSession;
		this.projectDependenciesResolver = projectDependenciesResolver;
		this.systemPackages = systemPackages;
		this.log = log;
		javaPackages = Utils.getJavaPackages(log);
	}

	public Set<BundleArtifact> getBundleDependencies(String... scopes)
			throws MojoExecutionException {
		ScopeDependencyFilter scopeFilter = new ScopeDependencyFilter(Arrays.asList(scopes), null);

		DefaultDependencyResolutionRequest dependencyResolutionRequest = new DefaultDependencyResolutionRequest(
				project, repositorySystemSession);
		dependencyResolutionRequest.setResolutionFilter(scopeFilter);

		DependencyResolutionResult dependencyResolutionResult;
		try {
			dependencyResolutionResult = projectDependenciesResolver
					.resolve(dependencyResolutionRequest);
		} catch (DependencyResolutionException ex) {
			throw new MojoExecutionException(ex.getMessage(), ex);
		}

		DependencyNode dependencyGraph = dependencyResolutionResult.getDependencyGraph();
		if (dependencyGraph != null) {
			checkBundleDependencies(dependencyGraph.getChildren());
			return getBundleArtifacts(dependencyGraph.getChildren());
		} else {
			return new HashSet<BundleArtifact>();
		}
	}

	public Set<BundleArtifact> getBundleArtifacts(List<DependencyNode> nodes) {
		Set<BundleArtifact> bundleArtifacts = new HashSet<BundleArtifact>();
		for (DependencyNode node : nodes) {
			Artifact artifact = RepositoryUtils.toArtifact(node.getDependency().getArtifact());
			String symbolicName = getManifestAttribute(artifact, Constants.BUNDLE_SYMBOLICNAME);
			if (symbolicName != null) {
				String version = getManifestAttribute(artifact, Constants.BUNDLE_VERSION);
				bundleArtifacts.add(new BundleArtifact(artifact, symbolicName, version));
				bundleArtifacts.addAll(getBundleArtifacts(node.getChildren()));
			} else {
				log.warn("Not an OSGi bundle : " + artifact.getId());
			}
		}
		return bundleArtifacts;
	}

	public Set<Artifact> getAllArtifacts(List<DependencyNode> nodes) {
		Set<Artifact> artifacts = new HashSet<Artifact>();
		for (DependencyNode node : nodes) {
			Artifact artifact = RepositoryUtils.toArtifact(node.getDependency().getArtifact());
			if (isBundle(artifact)) {
				artifacts.add(artifact);
				artifacts.addAll(getAllArtifacts(node.getChildren()));
			}
		}
		return artifacts;
	}

	public Set<Artifact> getArtifacts(List<DependencyNode> nodes) {
		Set<Artifact> artifacts = new HashSet<Artifact>();
		for (DependencyNode node : nodes) {
			Artifact artifact = RepositoryUtils.toArtifact(node.getDependency().getArtifact());
			if (isBundle(artifact)) {
				artifacts.add(artifact);
			}
		}
		return artifacts;
	}

	public List<BundleInfo> getBundles(Set<BundleArtifact> bundleDependencies)
			throws MojoExecutionException {
		List<BundleInfo> bundles = new ArrayList<BundleInfo>();
		for (BundleArtifact bundleArtifact : bundleDependencies) {
			Artifact artifact = bundleArtifact.getArtifact();
			BundleInfo bundle = new BundleInfo();
			bundle.setSymbolicName(bundleArtifact.getSymbolicName());
			bundle.setVersion(bundleArtifact.getVersion());
			bundle.setFileName(new File(artifact.getGroupId(), artifact.getFile().getName())
					.getPath());
			bundles.add(bundle);
		}
		Collections.sort(bundles, new BundleComparator());
		return bundles;
	}

	public Map<String, Set<PackageVersion>> getPackageDependencies(List<DependencyNode> nodes) {
		Map<String, Set<PackageVersion>> exportVersions = calculatePackageVersions(
				getAllArtifacts(nodes), true, false);
		return getPackageDependencies(getArtifacts(nodes), exportVersions);
	}

	public Map<String, Set<PackageVersion>> getPackageDependencies(Set<Artifact> requiredArtifacts,
			Map<String, Set<PackageVersion>> exportVersions) {
		Map<String, Set<PackageVersion>> importVersions = calculatePackageVersions(
				requiredArtifacts, false, true);
		Set<Artifact> newRequiredArtifacts = new HashSet<Artifact>();
		for (Entry<String, Set<PackageVersion>> entry : importVersions.entrySet()) {
			if (!javaPackages.contains(entry.getKey())) {
				String packageName = entry.getKey();
				Set<PackageVersion> importsVersions = entry.getValue();
				Set<PackageVersion> exportsVersions = exportVersions.get(packageName);
				if (exportVersions.containsKey(entry.getKey())) {
					for (Artifact artifact : getRequiredArtifacts(importsVersions, exportsVersions)) {
						if (!requiredArtifacts.contains(artifact)) {
							newRequiredArtifacts.add(artifact);
						}
					}
				}
			}
		}
		if (!newRequiredArtifacts.isEmpty()) {
			newRequiredArtifacts.addAll(requiredArtifacts);
			return getPackageDependencies(newRequiredArtifacts, exportVersions);
		}
		return importVersions;
	}

	/**
	 * Returns the minimum set of artifacts required to satisfy the range of importVersions.
	 *
	 * @param importsVersions
	 *            the version ranges required for the package
	 * @param exportVersions
	 *            the available versions for the package
	 * @return the minimum set of artifacts required to satisfy the range of importVersions
	 */
	private Set<Artifact> getRequiredArtifacts(Set<PackageVersion> importsVersions,
			Set<PackageVersion> exportVersions) {
		Set<Artifact> requiredArtifacts = new HashSet<Artifact>();
		List<Set<PackageVersion>> exportsSubsets = Utils.getSubsets(exportVersions);
		for (Set<PackageVersion> exportsSubset : exportsSubsets) {
			if (satisfiesImports(importsVersions, exportsSubset)) {
				for (PackageVersion exportVersion : exportsSubset) {
					requiredArtifacts.add(exportVersion.getArtifact());
				}
				break;
			}
		}
		return requiredArtifacts;
	}

	private boolean satisfiesImports(Set<PackageVersion> imports, Set<PackageVersion> exports) {
		for (PackageVersion importVersion : imports) {
			if (!satisfiesImport(importVersion, exports)) {
				return false;
			}
		}
		return true;
	}

	private boolean satisfiesImport(PackageVersion importVersion, Set<PackageVersion> exports) {
		for (PackageVersion exportVersion : exports) {
			if (importVersion.getVersionRange().includes(exportVersion.getVersionRange().getLow())) {
				return true;
			}
		}
		return false;
	}

	public void checkBundleDependencies(List<DependencyNode> nodes) {
		Map<Artifact, Set<Package>> unresolvedArtifacts = new HashMap<Artifact, Set<Package>>();
		Set<Artifact> artifacts = getAllArtifacts(nodes);
		Map<String, Set<PackageVersion>> exports = calculatePackageVersions(artifacts, true, false);
		for (Artifact artifact : artifacts) {
			if (isBundle(artifact)) {
				Parameters imports = getManifestAttributeParameters(artifact,
						Constants.IMPORT_PACKAGE);
				if (imports != null) {
					for (String packageName : imports.keySet()) {
						boolean exportMissing = true;
						VersionRange importRange = null;
						Attrs attrs = imports.get(packageName);
						if (isOptional(attrs)) {
							exportMissing = false;
						} else if (javaPackages.contains(packageName)
								|| systemPackages.contains(packageName)
								|| packageName.startsWith("org.osgi.")) {
							exportMissing = false;
						} else if (attrs == null || attrs.get(Constants.VERSION_ATTRIBUTE) == null) {
							if (exports.containsKey(packageName)) {
								exportMissing = false;
							}
						} else {
							importRange = getVersionRange(attrs);
							if (exports.containsKey(packageName)) {
								for (PackageVersion exportVersion : exports.get(packageName)) {
									if (importRange.includes(exportVersion.getVersionRange()
											.getLow())) {
										exportMissing = false;
										break;
									}
								}
							}
						}
						if (exportMissing) {
							if (!unresolvedArtifacts.containsKey(artifact)) {
								unresolvedArtifacts.put(artifact, new HashSet<Package>());
							}
							unresolvedArtifacts.get(artifact).add(
									new Package(packageName, importRange));
						}
					}
				}
			}
		}
		for (Entry<Artifact, Set<Package>> unresolvedArtifact : unresolvedArtifacts.entrySet()) {
			log.warn("Bundle : " + unresolvedArtifact.getKey().getId()
					+ " has unresolved package dependencies:");
			for (Package unresolvedPackage : unresolvedArtifact.getValue()) {
				log.warn("    " + unresolvedPackage);
			}
		}
	}

	public Map<String, Set<PackageVersion>> calculatePackageVersions(Set<Artifact> artifacts,
			boolean export, boolean unique) {
		Map<String, Set<PackageVersion>> packageVersions = new HashMap<String, Set<PackageVersion>>();
		for (Artifact artifact : artifacts) {
			if (isBundle(artifact)) {
				Parameters packages = getManifestAttributeParameters(artifact,
						export ? Constants.EXPORT_PACKAGE : Constants.IMPORT_PACKAGE);
				if (packages != null) {
					for (String packageName : packages.keySet()) {
						if (!packageVersions.containsKey(packageName)) {
							packageVersions.put(packageName, new HashSet<PackageVersion>());
						}
						Set<PackageVersion> versions = packageVersions.get(packageName);
						VersionRange versionRange = getVersionRange(packages.get(packageName));
						boolean optional = isOptional(packages.get(packageName));
						if (unique) {
							// check if this version range is unique
							boolean uniqueVersion = true;
							for (PackageVersion version : versions) {
								if (equals(versionRange, version.getVersionRange())) {
									uniqueVersion = false;
									break;
								}
							}
							if (uniqueVersion) {
								versions.add(new PackageVersion(versionRange, artifact, optional));
							}
						} else {
							versions.add(new PackageVersion(versionRange, artifact, optional));
						}
					}
				}
			}
		}
		return packageVersions;
	}

	public Version getVersion(Attrs attrs) {
		if (attrs == null) {
			return Version.LOWEST;
		}
		return Version.parseVersion(attrs.get(Constants.VERSION_ATTRIBUTE));
	}

	public VersionRange getVersionRange(Attrs attrs) {
		if (attrs == null) {
			return new VersionRange("0");
		}
		String version = attrs.get(Constants.VERSION_ATTRIBUTE);
		if (version == null) {
			return new VersionRange("0");
		}
		return new VersionRange(version);
	}

	public boolean isBundle(Artifact artifact) {
		return getManifestAttribute(artifact, Constants.BUNDLE_SYMBOLICNAME) != null;
	}

	public boolean isOptional(Attrs attrs) {
		return attrs != null && "optional".equals(attrs.get(Constants.RESOLUTION_DIRECTIVE));
	}

	public boolean equals(VersionRange v1, VersionRange v2) {
		return v1 == v2 || v1.toString().equals(v2.toString());
	}

	public Parameters getManifestAttributeParameters(Artifact artifact, String attributeName) {
		String attributeValue = getManifestAttribute(artifact, attributeName);
		if (attributeValue != null) {
			return OSGiHeader.parseHeader(attributeValue);
		}
		return null;
	}

	public String getManifestAttribute(Artifact artifact, String attributeName) {
		Manifest manifest = getManifest(artifact);
		if (manifest != null) {
			Attributes mainAttributes = manifest.getMainAttributes();
			return mainAttributes.getValue(attributeName);
		}
		return null;
	}

	public Manifest getManifest(Artifact artifact) {
		if (artifact != null) {
			File file = artifact.getFile();
			if (file != null) {
				try {
					JarFile jarFile = new JarFile(artifact.getFile());
					return jarFile.getManifest();
				} catch (IOException e) {
					return null;
				}
			}
		}
		return null;
	}

	private final class BundleComparator implements Comparator<BundleInfo> {

		@Override
		public int compare(BundleInfo bundle1, BundleInfo bundle2) {
			return bundle1.getSymbolicName().compareTo(bundle2.getSymbolicName());
		}

	}

	// public static void main(String[] args) throws Exception {
	// MavenOsgiUtils mavenOsgiUtils = new MavenOsgiUtils();
	// Parameters exports = mavenOsgiUtils.getImports(new
	// File("/Users/david/Documents/workspace-trunk/taverna-plugin-impl/target/taverna-plugin-impl-0.1.0-SNAPSHOT.jar"));
	// for (String key : exports.keySet()) {
	// System.out.println(key + " " + mavenOsgiUtils.getVersionRange(exports.get(key)));
	// }
	// }
}
