package aQute.bnd.deployer.repository.wrapper;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.service.repository.Repository;

import aQute.bnd.build.Workspace;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.resource.FilterParser;
import aQute.bnd.service.Registry;
import aQute.bnd.service.RegistryDonePlugin;
import aQute.bnd.service.RegistryPlugin;
import aQute.bnd.service.repository.InfoRepository;
import aQute.lib.collections.MultiMap;
import aQute.lib.converter.Converter;
import aQute.lib.io.IO;
import aQute.libg.reporter.ReporterAdapter;
import aQute.service.reporter.Reporter;

public class Plugin implements aQute.bnd.service.Plugin, RegistryPlugin, RegistryDonePlugin, Repository {

	private Registry				registry;
	private Config					config;
	private Reporter				reporter	= new ReporterAdapter();
	private File					dir;
	private InfoRepositoryWrapper	wrapper;

	interface Config {
		String location();

		boolean reindex();

		String augments();

		boolean reset_cache();
	}

	public void setRegistry(Registry registry) {
		this.registry = registry;
	}

	public void setProperties(Map<String,String> map) throws Exception {
		config = Converter.cnv(Config.class, map);
		File file = IO.getFile(config.location());
		file.mkdirs();
		if (!file.isDirectory()) {
			reporter.error("Repository Wrapper: cannot create cache: %s", file);
		}
		this.dir = file;
	}

	public void setReporter(Reporter reporter) {
		this.reporter = reporter;
	}

	/**
	 * This is called when all initialization is done for the plugins, now we
	 * can obtain a list of appropriate repos.
	 */
	public void done() throws Exception {
		try {

			//
			// Get the list if repos registered, repos that we can handle
			//

			List<InfoRepository> irs = new ArrayList<InfoRepository>();
			for (InfoRepository ir : registry.getPlugins(InfoRepository.class)) {
				irs.add(ir);
			}

			this.wrapper = new InfoRepositoryWrapper(dir, irs);

			if (config.reindex())
				this.wrapper.clear();

			// An augment file was specified, this specifies extra
			// reqs and caps for the analyzed files
			//

			if (config.augments() != null) {

				Workspace workspace = registry.getPlugin(Workspace.class);
				Processor p = new Processor(workspace);
				try {

					if (!config.augments().equals("WORKSPACE")) {
						File f = IO.getFile(workspace.getBuildDir(), config.augments());
						if (!f.isFile()) {
							if (reporter != null)
								reporter.error("No augment file found at %s", f.getAbsolutePath());
							return;
						}

						//
						// We read this in a processor that extends the
						// workspace so
						// we
						// can use workspace properties
						//

						p.setProperties(f);
						this.wrapper.clear(f.lastModified());
					}

					//
					// And then add it to the indexer to use.
					//

					this.wrapper.addAugment(p.getFlattenedProperties());
					this.wrapper.clear(workspace.getPropertiesFile().lastModified());
				}
				finally {
					p.close();
				}
			}

		}
		catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	FilterParser fp = new FilterParser();

	@SuppressWarnings({
			"unchecked", "rawtypes"
	})
	public Map<Requirement,Collection<Capability>> findProviders(Collection< ? extends Requirement> requirements) {
		MultiMap<Requirement,Capability> result = new MultiMap<Requirement,Capability>();
		try {
			wrapper.findProviders(result, requirements);
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		return (Map) result;
	}

	public String toString() {
		return wrapper != null ? wrapper.toString() : "<wrapper not set>";
	}

}

@@ -41,16 +41,42 @@
 apper;%0A%0A
+import java.io.Closeable;%0A
 import j
@@ -888,16 +888,27 @@
 pository
+, Closeable
  %7B%0A%0A%09pri
@@ -3254,16 +3254,139 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09public void close() throws java.io.IOException %7B%0A%09%09if (this.wrapper == null) %7B%0A%09%09%09return;%0A%09%09%7D%0A%09%09this.wrapper.close();%0A%09%7D%0A%0A
 %09FilterP

Implement Closeable so we can cleanup after ourselves