/*******************************************************************************
 * Copyright (c) 2005, 2017 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.loader.classpath;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
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.Manifest;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.framework.util.KeyedHashSet;
import org.eclipse.osgi.storage.BundleInfo;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.Storage;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.storage.bundlefile.BundleFile;

/**
 * A ClasspathEntry contains a single <code>BundleFile</code> which is used as 
 * a source to load classes and resources from, and a single 
 * <code>ProtectionDomain</code> which is used as the domain to define classes 
 * loaded from this ClasspathEntry.
 * @since 3.2
 */
public class ClasspathEntry {
	static final class PDEData {
		final String fileName;
		final String symbolicName;

		PDEData(File baseFile, String symbolicName) {
			this.fileName = baseFile == null ? null : baseFile.getAbsolutePath();
			this.symbolicName = symbolicName;
		}
	}

	private final BundleFile bundlefile;
	private final ProtectionDomain domain;
	private final ManifestPackageAttributes mainManifestPackageAttributes;
	private final Map<String, ManifestPackageAttributes> perPackageManifestAttributes;
	private final List<BundleFile> mrBundleFiles;
	private KeyedHashSet userObjects = null;

	// TODO Note that PDE has internal dependency on this field type/name (bug 267238)
	@SuppressWarnings("unused")
	private final PDEData data;

	/**
	 * Constructs a ClasspathElement with the specified bundlefile and domain
	 * @param bundlefile A BundleFile object which acts as a source
	 * @param domain the protection domain
	 */
	public ClasspathEntry(BundleFile bundlefile, ProtectionDomain domain, Generation generation) {
		this.bundlefile = bundlefile;
		this.domain = domain;
		this.data = new PDEData(generation.getBundleFile().getBaseFile(), generation.getRevision().getSymbolicName());
		final Manifest manifest = loadManifest(bundlefile, generation);
		if (manifest != null && generation.getBundleInfo().getStorage().getConfiguration().DEFINE_PACKAGE_ATTRIBUTES) {
			mainManifestPackageAttributes = manifestPackageAttributesFor(manifest.getMainAttributes(), null);
			perPackageManifestAttributes = manifestPackageAttributesMapFor(manifest.getEntries().entrySet(), mainManifestPackageAttributes);
		} else {
			mainManifestPackageAttributes = ManifestPackageAttributes.NONE;
			perPackageManifestAttributes = null;
		}

		boolean isMRJar;
		if (bundlefile == generation.getBundleFile()) {
			// this is the root bundle file
			isMRJar = generation.isMRJar();
		} else {
			isMRJar = manifest != null ? Boolean.parseBoolean(manifest.getMainAttributes().getValue(BundleInfo.MULTI_RELEASE_HEADER)) : false;
		}
		if (isMRJar) {
			mrBundleFiles = getMRBundleFiles(bundlefile, generation);
		} else {
			mrBundleFiles = Collections.emptyList();
		}
	}

	private static List<BundleFile> getMRBundleFiles(BundleFile bundlefile, Generation generation) {
		Storage storage = generation.getBundleInfo().getStorage();
		if (storage.getRuntimeVersion().getMajor() < 9) {
			return Collections.emptyList();
		}
		List<BundleFile> mrBundleFiles = new ArrayList<>();
		for (int i = storage.getRuntimeVersion().getMajor(); i > 8; i--) {
			String versionPath = BundleInfo.MULTI_RELEASE_VERSIONS + i + '/';
			BundleEntry versionEntry = bundlefile.getEntry(versionPath);
			if (versionEntry != null) {
				mrBundleFiles.add(storage.createNestedBundleFile(versionPath, bundlefile, generation, BundleInfo.MULTI_RELEASE_FILTER_PREFIXES));
			}
		}
		return Collections.unmodifiableList(mrBundleFiles);
	}

	private static ManifestPackageAttributes manifestPackageAttributesFor(Attributes attributes, ManifestPackageAttributes defaultAttributes) {
		return ManifestPackageAttributes.of(attributes.getValue(Attributes.Name.SPECIFICATION_TITLE), //
				attributes.getValue(Attributes.Name.SPECIFICATION_VERSION), //
				attributes.getValue(Attributes.Name.SPECIFICATION_VENDOR), //
				attributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE), //
				attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION), //
				attributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR), //
				defaultAttributes);
	}

	private static Map<String, ManifestPackageAttributes> manifestPackageAttributesMapFor(Set<Entry<String, Attributes>> entries, ManifestPackageAttributes defaultAttributes) {
		Map<String, ManifestPackageAttributes> result = null;
		for (Entry<String, Attributes> entry : entries) {
			String name = entry.getKey();
			Attributes attributes = entry.getValue();
			if (name != null && name.endsWith("/")) { //$NON-NLS-1$
				String packageName = name.substring(0, name.length() - 1).replace('/', '.');
				if (result == null) {
					result = new HashMap<>(4);
				}
				result.put(packageName, manifestPackageAttributesFor(attributes, defaultAttributes));
			}
		}
		return result;
	}

	/**
	 * Returns the source BundleFile for this classpath entry
	 * @return the source BundleFile for this classpath entry
	 */
	public BundleFile getBundleFile() {
		return bundlefile;
	}

	/**
	 * Returns the ProtectionDomain for this classpath entry
	 * @return the ProtectionDomain for this classpath entry
	 */
	public ProtectionDomain getDomain() {
		return domain;
	}

	/**
	 * Returns a user object which is keyed by the specified key
	 * @param key the key of the user object to get
	 * @return a user object which is keyed by the specified key
	 */
	public synchronized Object getUserObject(Object key) {
		if (userObjects == null)
			return null;
		return userObjects.getByKey(key);

	}

	/**
	 * Adds a user object
	 * @param userObject the user object to add
	 */
	public synchronized void addUserObject(KeyedElement userObject) {
		if (userObjects == null)
			userObjects = new KeyedHashSet(5, false);
		userObjects.add(userObject);
	}

	/**
	 * Finds the entry with the specified path.
	 * This handles Multi-Release searching also.
	 * @param path the path to find
	 * @return the entry with the specified path.
	 */
	public BundleEntry findEntry(String path) {
		for (BundleFile mrFile : mrBundleFiles) {
			BundleEntry mrEntry = mrFile.getEntry(path);
			if (mrEntry != null) {
				return mrEntry;
			}
		}
		return bundlefile.getEntry(path);
	}

	/**
	 * Finds the resource wiht the specified name.
	 * This handles Multi-Release searching also.
	 * @param name the resource name
	 * @param m the module this classpath entry is for
	 * @param index the index this classpath entry.
	 * @return the resource URL or {@code null} if the resource does not exist.
	 */
	public URL findResource(String name, Module m, int index) {
		for (BundleFile mrFile : mrBundleFiles) {
			URL mrURL = mrFile.getResourceURL(name, m, index);
			if (mrURL != null) {
				return mrURL;
			}
		}
		return bundlefile.getResourceURL(name, m, index);
	}

	/**
	 * Adds the BundleFile objects for this classpath in the proper order
	 * for searching for resources. This handles Multi-Release ordering also.
	 * @param bundlefiles
	 */
	public void addBundleFiles(List<BundleFile> bundlefiles) {
		bundlefiles.addAll(mrBundleFiles);
		bundlefiles.add(bundlefile);
	}

	private static Manifest loadManifest(BundleFile cpBundleFile, Generation generation) {
		if (!generation.hasPackageInfo() && generation.getBundleFile() == cpBundleFile) {
			return null;
		}
		BundleEntry mfEntry = cpBundleFile.getEntry(BundleInfo.OSGI_BUNDLE_MANIFEST);
		if (mfEntry != null) {
			InputStream manIn = null;
			try {
				try {
					manIn = mfEntry.getInputStream();
					return new Manifest(manIn);
				} finally {
					if (manIn != null)
						manIn.close();
				}
			} catch (IOException e) {
				// do nothing
			}
		}
		return null;
	}

	ManifestPackageAttributes manifestPackageAttributesFor(String packageName) {
		ManifestPackageAttributes perPackage = perPackageManifestAttributes == null ? null : perPackageManifestAttributes.get(packageName);
		if (perPackage != null) {
			return perPackage;
		}
		return mainManifestPackageAttributes;
	}

	public void close() throws IOException {
		bundlefile.close();
		for (BundleFile bf : mrBundleFiles) {
			bf.close();
		}
	}
}
