package aQute.lib.deployer.obr;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import aQute.bnd.build.ResolverMode;
import aQute.bnd.service.OBRIndexProvider;
import aQute.bnd.service.OBRResolutionMode;
import aQute.bnd.service.Plugin;
import aQute.bnd.service.Registry;
import aQute.bnd.service.RegistryPlugin;
import aQute.bnd.service.RemoteRepositoryPlugin;
import aQute.bnd.service.ResourceHandle;
import aQute.bnd.service.ResourceHandle.Location;
import aQute.lib.filter.Filter;
import aQute.lib.osgi.Jar;
import aQute.libg.generics.Create;
import aQute.libg.reporter.Reporter;
import aQute.libg.version.Version;
import aQute.libg.version.VersionRange;

/**
 * Abstract base class for OBR-based repositories.
 * 
 * <p>
 * The repository implementation is read-only by default. To implement a writable
 * repository, subclasses should override {@link #canWrite()} and {@link #put(Jar)}.
 * 
 * @author Neil Bartlett
 *
 */
public abstract class AbstractBaseOBR implements RegistryPlugin, Plugin, RemoteRepositoryPlugin, OBRIndexProvider {
	
	public static final String PROP_NAME = "name";
	public static final String PROP_RESOLUTION_MODE = "mode";
	public static final String PROP_RESOLUTION_MODE_ANY = "any";
	
	public static final String REPOSITORY_FILE_NAME = "repository.xml";
	
	protected Registry registry;
	protected Reporter reporter;
	protected String name = this.getClass().getName();
	protected Set<OBRResolutionMode> supportedModes = EnumSet.allOf(OBRResolutionMode.class);

	private boolean initialised = false;
	private final Map<String, SortedMap<Version, Resource>> pkgResourceMap = new HashMap<String, SortedMap<Version, Resource>>();
	private final Map<String, SortedMap<Version, Resource>> bsnMap = new HashMap<String, SortedMap<Version, Resource>>();
	
	protected abstract File getCacheDirectory();

	protected void addResourceToIndex(Resource resource) {
		addBundleSymbolicNameToIndex(resource);
		addPackagesToIndex(resource);
	}

	protected synchronized void reset() {
		initialised = false;
	}

	/**
	 * Initialise the indexes prior to main initialisation of internal
	 * data structures. This implementation does nothing, but subclasses
	 * may override if they need to perform such initialisation.
	 * @throws Exception 
	 */
	protected void initialiseIndexes() throws Exception {
	}

	protected final synchronized void init() throws Exception {
		if (!initialised) {
			bsnMap.clear();
			pkgResourceMap.clear();
			
			initialiseIndexes();
			
			IResourceListener listener = new IResourceListener() {
				public boolean processResource(Resource resource) {
					addResourceToIndex(resource);
					return true;
				}
			};
			Collection<URL> indexes = getOBRIndexes();
			for (URL indexLocation : indexes) {
				try {
					InputStream stream = indexLocation.openStream();
					readIndex(indexLocation.toString(), stream, listener);
				} catch (Exception e) {
					e.printStackTrace();
					reporter.error("Unable to read index at URL '%s'.", indexLocation);
				}
			}
			
			initialised = true;
		}
	}
	
	public void setRegistry(Registry registry) {
		this.registry = registry;
	}

	public void setProperties(Map<String, String> map) {
		if (map.containsKey(PROP_NAME))
			name = map.get(PROP_NAME);
		
		if (map.containsKey(PROP_RESOLUTION_MODE)) {
			supportedModes = EnumSet.noneOf(OBRResolutionMode.class);
			StringTokenizer tokenizer = new StringTokenizer(map.get(PROP_RESOLUTION_MODE), ",");
			while (tokenizer.hasMoreTokens()) {
				String token = tokenizer.nextToken().trim();
				if (PROP_RESOLUTION_MODE_ANY.equalsIgnoreCase(token))
					supportedModes = EnumSet.allOf(OBRResolutionMode.class);
				else {
					try {
						supportedModes.add(OBRResolutionMode.valueOf(token));
					} catch (Exception e) {
						if (reporter != null) reporter.error("Unknown OBR resolution mode: " + token);
					}
				}
			}
		}
	}
	
	public File[] get(String bsn, String range) throws Exception {
		ResourceHandle[] handles = getHandles(bsn, range);
		
		return requestAll(handles);
	}
	
	protected static File[] requestAll(ResourceHandle[] handles) throws IOException {
		File[] result = (handles == null) ? new File[0] : new File[handles.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = handles[i].request();
		}
		return result;
	}

	protected ResourceHandle[] getHandles(String bsn, String rangeStr) throws Exception {
		init();
		
		// If the range is set to "project", we cannot resolve it.
		if ("project".equals(rangeStr))
			return null;
		
		
		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
		if (versionMap == null || versionMap.isEmpty())
			return null;
		List<Resource> resources = narrowVersionsByVersionRange(versionMap, rangeStr);
		List<ResourceHandle> handles = mapResourcesToHandles(resources);
		
		return (ResourceHandle[]) handles.toArray(new ResourceHandle[handles.size()]);
	}
	
	public void setReporter(Reporter reporter) {
		this.reporter = reporter;
	}
	
	public File get(String bsn, String range, Strategy strategy, Map<String, String> properties) throws Exception {
		ResourceHandle handle = getHandle(bsn, range, strategy, properties);
		return handle != null ? handle.request() : null;
	}
	
	public ResourceHandle getHandle(String bsn, String range, Strategy strategy, Map<String, String> properties) throws Exception {
		ResourceHandle result;
		if (bsn != null)
			result = resolveBundle(bsn, range, strategy);
		else {
			String pkgName = properties.get(CapabilityType.PACKAGE.getTypeName());
			
			String modeName = properties.get(CapabilityType.MODE.getTypeName());
			ResolverMode mode = (modeName != null) ? ResolverMode.valueOf(modeName) : null;
			
			if (pkgName != null)
				result = resolvePackage(pkgName, range, strategy, mode, properties);
			else
				throw new IllegalArgumentException("Cannot resolve bundle: neither bsn nor package specified.");
		}
		return result;
	}

	public boolean canWrite() {
		return false;
	}

	public File put(Jar jar) throws Exception {
		throw new UnsupportedOperationException("Read-only repository.");
	}

	public List<String> list(String regex) throws Exception {
		init();
		Pattern pattern = regex != null ? Pattern.compile(regex) : null;
		List<String> result = new LinkedList<String>();
		
		for (String bsn : bsnMap.keySet()) {
			if (pattern == null || pattern.matcher(bsn).matches())
				result.add(bsn);
		}
		
		return result;
	}

	public List<Version> versions(String bsn) throws Exception {
		init();
		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
		List<Version> list;
		if (versionMap != null) {
			list = new ArrayList<Version>(versionMap.size());
			list.addAll(versionMap.keySet());
		} else {
			list = Collections.emptyList();
		}
		return list;
	}

	public String getName() {
		return name;
	}

	void addBundleSymbolicNameToIndex(Resource resource) {
		String bsn = resource.getSymbolicName();
		Version version;
		String versionStr = resource.getVersion();
		try {
			version = new Version(versionStr);
		} catch (Exception e) {
			version = new Version("0.0.0");
		}
		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
		if (versionMap == null) {
			versionMap = new TreeMap<Version, Resource>();
			bsnMap.put(bsn, versionMap);
		}
		versionMap.put(version, resource);
	}

	void addPackagesToIndex(Resource resource) {
		for (Capability capability : resource.getCapabilities()) {
			if (CapabilityType.PACKAGE.getTypeName().equals(capability.getName())) {
				String pkgName = null;
				String versionStr = null;
				
				for (Property prop : capability.getProperties()) {
					if (Property.PACKAGE.equals(prop.getName()))
						pkgName = prop.getValue();
					else if (Property.VERSION.equals(prop.getName()))
						versionStr = prop.getValue();
				}
				
				Version version;
				try {
					version = new Version(versionStr);
				} catch (Exception e) {
					version = new Version("0.0.0");
				}
				
				if (pkgName != null) {
					SortedMap<Version, Resource> versionMap = pkgResourceMap.get(pkgName);
					if (versionMap == null) {
						versionMap = new TreeMap<Version, Resource>();
						pkgResourceMap.put(pkgName, versionMap);
					}
					versionMap.put(version, resource);
				}
			}
		}
	}

	/**
	 * @return Whether to continue parsing other indexes
	 * @throws IOException 
	 */
	boolean readIndex(String baseUrl, InputStream stream, IResourceListener listener) throws ParserConfigurationException, SAXException, IOException {
		SAXParserFactory parserFactory = SAXParserFactory.newInstance();
		SAXParser parser = parserFactory.newSAXParser();
		try {
			parser.parse(stream, new OBRSAXHandler(baseUrl, listener));
			return true;
		} catch (StopParseException e) {
			return false;
		} finally {
			stream.close();
		}
	}

	List<Resource> narrowVersionsByFilter(String pkgName, SortedMap<Version, Resource> versionMap, Filter filter) {
		List<Resource> result = new ArrayList<Resource>(versionMap.size());
		
		Dictionary<String, String> dict = new Hashtable<String, String>();
		dict.put("package", pkgName);
		
		for (Version version : versionMap.keySet()) {
			dict.put("version", version.toString());
			if (filter.match(dict))
				result.add(versionMap.get(version));
		}
		
		return result;
	}

	List<Resource> narrowVersionsByVersionRange(SortedMap<Version, Resource> versionMap, String rangeStr) {
		List<Resource> result;
		if ("latest".equals(rangeStr)) {
			Version highest = versionMap.lastKey();
			result = Create.list(new Resource[] { versionMap.get(highest) });
		} else {
			VersionRange range = rangeStr != null ? new VersionRange(rangeStr) : null;
			
			// optimisation: skip versions definitely less than the range
			if (range != null && range.getLow() != null)
				versionMap = versionMap.tailMap(range.getLow());
			
			result = new ArrayList<Resource>(versionMap.size());
			for (Version version : versionMap.keySet()) {
				if (range == null || range.includes(version))
					result.add(versionMap.get(version));
				
				// optimisation: skip versions definitely higher than the range
				if (range != null && range.isRange() && version.compareTo(range.getHigh()) >= 0)
					break;
			}
		}
		return result;
	}
	
	void filterResourcesByResolverMode(Collection<Resource> resources, ResolverMode mode) {
		assert mode != null;
		
		Properties modeCapability = new Properties();
		modeCapability.setProperty(CapabilityType.MODE.getTypeName(), mode.name());
		
		for (Iterator<Resource> iter = resources.iterator(); iter.hasNext(); ) {
			Resource resource = iter.next();
			
			Require modeRequire = resource.findRequire(CapabilityType.MODE.getTypeName());
			if (modeRequire == null)
				continue;
			else if (modeRequire.getFilter() == null)
				iter.remove();
			else {
				try {
					Filter filter = new Filter(modeRequire.getFilter());
					if (!filter.match(modeCapability))
						iter.remove();
				} catch (IllegalArgumentException e) {
					if (reporter != null)
						reporter.error("Error parsing mode filter requirement on resource %s: %s", resource.getUrl(), modeRequire.getFilter());
					iter.remove();
				}
			}
		}
	}
	
	List<ResourceHandle> mapResourcesToHandles(Collection<Resource> resources) throws Exception {
		List<ResourceHandle> result = new ArrayList<ResourceHandle>(resources.size());
		
		for (Resource resource : resources) {
			ResourceHandle handle = mapResourceToHandle(resource);
			if (handle != null)
				result.add(handle);
		}
		
		return result;
	}
	
	ResourceHandle mapResourceToHandle(Resource resource) throws Exception {
		ResourceHandle result = null;
		
		URLResourceHandle handle ;
		try {
			handle = new URLResourceHandle(resource.getUrl(), resource.getBaseUrl(), getCacheDirectory());
		} catch (FileNotFoundException e) {
			throw new FileNotFoundException("Broken link in repository index: " + e.getMessage());
		}
		if (handle.getLocation() == Location.local || getCacheDirectory() != null)
			result = handle;
		
		return result;
	}

	ResourceHandle resolveBundle(String bsn, String rangeStr, Strategy strategy) throws Exception {
		if (rangeStr == null) rangeStr = "0.0.0";
		
		if (strategy == Strategy.EXACT) {
			return findExactMatch(bsn, rangeStr, bsnMap);
		}
		
		ResourceHandle[] handles = getHandles(bsn, rangeStr);
		ResourceHandle selected;
		if (handles == null || handles.length == 0)
			selected = null;
		else {
			switch(strategy) {
			case LOWEST:
				selected = handles[0];
				break;
			default:
				selected = handles[handles.length - 1];
			}
		}
		return selected;
	}

	ResourceHandle resolvePackage(String pkgName, String rangeStr, Strategy strategy, ResolverMode mode, Map<String, String> props) throws Exception {
		init();
		if (rangeStr == null) rangeStr = "0.0.0";
		
		SortedMap<Version, Resource> versionMap = pkgResourceMap.get(pkgName);
		if (versionMap == null)
			return null;
		
		// Was a filter expression supplied?
		Filter filter = null;
		String filterStr = props.get("filter");
		if (filterStr != null) {
			filter = new Filter(filterStr);
		}
		
		// Narrow the resources by version range string or filter.
		List<Resource> resources;
		if (filter != null)
			resources = narrowVersionsByFilter(pkgName, versionMap, filter);
		else
			resources = narrowVersionsByVersionRange(versionMap, rangeStr);
		
		// Remove resources that are invalid for the current resolution mode
		if (mode != null)
			filterResourcesByResolverMode(resources, mode);
		
		// Select the most suitable one
		Resource selected;
		if (resources == null || resources.isEmpty())
			selected = null;
		else {
			switch (strategy) {
			case LOWEST:
				selected = resources.get(0);
				break;
			default:
				selected = resources.get(resources.size() - 1);
			}
			expandPackageUses(pkgName, selected, props);
		}
		return selected != null ? mapResourceToHandle(selected) : null;
	}

	void expandPackageUses(String pkgName, Resource resource, Map<String, String> props) {
		List<String> internalUses = new LinkedList<String>();
		Map<String, Require> externalUses = new HashMap<String, Require>();
		
		internalUses.add(pkgName);
		
		Capability capability = resource.findPackageCapability(pkgName);
		Property usesProp = capability.findProperty(Property.USES);
		if (usesProp != null) {
			StringTokenizer tokenizer = new StringTokenizer(usesProp.getValue(), ",");
			while (tokenizer.hasMoreTokens()) {
				String usesPkgName = tokenizer.nextToken();
				Capability usesPkgCap = resource.findPackageCapability(usesPkgName);
				if (usesPkgCap != null)
					internalUses.add(usesPkgName);
				else {
					Require require = resource.findPackageRequire(usesPkgName);
					if (require != null)
						externalUses.put(usesPkgName, require);
				}
			}
		}
		props.put("packages", listToString(internalUses));
		props.put("import-uses", formatPackageRequires(externalUses));
	}
	
	String listToString(List<?> list) {
		StringBuilder builder = new StringBuilder();
		
		int count = 0;
		for (Object item : list) {
			if (count++ > 0) builder.append(',');
			builder.append(item);
		}
		
		return builder.toString();
	}

	String formatPackageRequires(Map<String, Require> externalUses) {
		StringBuilder builder = new StringBuilder();
		
		int count = 0;
		for (Entry<String, Require> entry : externalUses.entrySet()) {
			String pkgName = entry.getKey();
			String filter = entry.getValue().getFilter();

			if (count++ > 0)
				builder.append(',');
			builder.append(pkgName);
			builder.append(";filter='");
			builder.append(filter);
			builder.append('\'');
		}
		
		return builder.toString();
	}

	ResourceHandle findExactMatch(String identity, String version, Map<String, SortedMap<Version, Resource>> resourceMap) throws Exception {
		Resource resource;
		VersionRange range = new VersionRange(version);
		if (range.isRange())
			return null;
		
		SortedMap<Version, Resource> versions = resourceMap.get(identity);
		resource = versions.get(range.getLow());
		
		return mapResourceToHandle(resource);
	}
	
	/**
	 * Utility function for parsing lists of URLs.
	 * 
	 * @param locationsStr
	 *            Comma-separated list of URLs
	 * @throws MalformedURLException
	 */
	protected static List<URL> parseLocations(String locationsStr) throws MalformedURLException {
		StringTokenizer tok = new StringTokenizer(locationsStr, ",");
		List<URL> urls = new ArrayList<URL>(tok.countTokens());
		while (tok.hasMoreTokens()) {
			String urlStr = tok.nextToken().trim();
			urls.add(new URL(urlStr));
		}
		return urls;
	}

	public Set<OBRResolutionMode> getSupportedModes() {
		return supportedModes;
	}

}
