/*******************************************************************************
 *  Copyright (c) 2017 SSI Schaefer IT Solutions GmbH 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:
 *      SSI Schaefer IT Solutions GmbH
 *******************************************************************************/
package org.eclipse.tea.library.build.model;

import static org.eclipse.tea.library.build.model.BundleData.splitList;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.tea.library.build.internal.Activator;

/**
 * Abstraction of the famous {@code MANIFEST.MF} file.
 * <p>
 * Supports manipulation of the manifest whilst keeping track of the order of
 * headers.
 */
final class ManifestHolder {

	private static final ParameterValue[] EMPTY_VALUES = {};

	private final Map<String, ManifestAttribute> attributes = new TreeMap<>();
	private final File referenceFile;

	private ManifestHolder(final Manifest manifest, final File referenceFile) {
		final Attributes attr = manifest.getMainAttributes();
		for (Object key : attr.keySet()) {
			final String name = key.toString();
			final String[] values = splitList(attr, name);
			attributes.put(name, new ManifestAttribute(name, values));
		}

		this.referenceFile = referenceFile;
	}

	static ManifestHolder fromManifest(Manifest manifest, File manifestFile) {
		if (manifest == null) {
			return null;
		}
		return new ManifestHolder(manifest, manifestFile);
	}

	/**
	 * Returns the value list to which the specified key is mapped, or
	 * {@code null} if this map contains no mapping for the key.
	 */
	private ParameterValue[] getValues(String key) {
		ManifestAttribute attr = attributes.get(key);
		if (attr == null) {
			return null;
		}
		return attr.values;
	}

	private ParameterValue[] safeList(String name) {
		ParameterValue[] result = getValues(name);
		if (result == null) {
			return EMPTY_VALUES;
		}
		return result;
	}

	ParameterValue[] getListAttribute(String name) {
		return safeList(name);
	}

	ParameterValue getSingleAttribute(String name) {
		return firstValue(name);
	}

	/**
	 * Returns the first parameter value to which the specified key is mapped,
	 * or {@code null} if this map contains no mapping for the key or there are
	 * no values.
	 */
	private ParameterValue firstValue(String key) {
		ParameterValue[] result = getValues(key);
		if (result == null || result.length < 1) {
			return null;
		}
		return result[0];
	}

	private String[] safeValueList(String name) {
		ParameterValue[] result = getValues(name);
		if (result == null) {
			return BundleData.EMPTY_STRINGS;
		}
		return ParameterValue.valuesFromList(result);
	}

	private String getSimple(String name) {
		ParameterValue pv = firstValue(name);
		if (pv == null) {
			return null;
		}
		return pv.getValue();
	}

	private boolean getBoolean(String name) {
		return Boolean.parseBoolean(getSimple(name));
	}

	private void putSimple(String name, String value) {
		attributes.put(name, new ManifestAttribute(name, value));
	}

	private void putList(String name, String[] values) {
		attributes.put(name, new ManifestAttribute(name, values));
	}

	private void putList(String name, ParameterValue[] values) {
		attributes.put(name, new ManifestAttribute(name, values));
	}

	ParameterValue getSymbolicName() {
		return firstValue("Bundle-SymbolicName");
	}

	String getDescription() {
		return getSimple("Bundle-Name");
	}

	String getActivator() {
		return getSimple("Bundle-Activator");
	}

	void setActivator(String activator) {
		if (activator == null) {
			attributes.remove("Bundle-Activator");
		} else {
			putSimple("Bundle-Activator", activator);
		}
	}

	void addDependency(String pluginName, boolean optional) {
		ManifestAttribute reqBundleAttr = attributes.get("Require-Bundle");
		ParameterValue[] dependencies = reqBundleAttr.values;
		ParameterValue[] newDependecies = new ParameterValue[dependencies.length + 1];
		System.arraycopy(dependencies, 0, newDependecies, 0, dependencies.length);

		String param = optional ? ";resolution:=optional" : "";
		newDependecies[newDependecies.length - 1] = new ParameterValue(pluginName + param);

		ManifestAttribute manifestAttr = new ManifestAttribute("Require-Bundle", newDependecies);
		attributes.put("Require-Bundle", manifestAttr);
	}

	ParameterValue[] getDependencies() {
		return safeList("Require-Bundle");
	}

	ParameterValue[] getMavenDependencies() {
		if (attributes.containsKey("WAMAS-Build-Maven")) {
			// DEPRECATED
			return safeList("WAMAS-Build-Maven");
		}
		return safeList("Build-Maven");
	}

	ParameterValue[] getImportPackages() {
		return safeList("Import-Package");
	}

	ParameterValue[] getExportPackages() {
		return safeList("Export-Package");
	}

	void setExportPackages(ParameterValue[] value) {
		if (value == null || value.length == 0) {
			attributes.remove("Export-Package");
		} else {
			putList("Export-Package", value);
		}
	}

	String getPlatformFilter() {
		return getSimple("Eclipse-PlatformFilter");
	}

	void setPlatformFilter(String value) {
		putSimple("Eclipse-PlatformFilter", value);
	}

	String[] getClassPath() {
		return safeValueList("Bundle-ClassPath");
	}

	void setClassPath(String[] values) {
		putList("Bundle-ClassPath", values);
	}

	ParameterValue[] getNativeCode() {
		return safeList("Bundle-NativeCode");
	}

	String[] getRequiredExecutionEnvironment() {
		return safeValueList("Bundle-RequiredExecutionEnvironment");
	}

	void setRequiredExecutionEnvironment(String[] values) {
		putList("Bundle-RequiredExecutionEnvironment", values);
	}

	void setAutomaticModuleName(String value) {
		putSimple("Automatic-Module-Name", value);
	}

	String getAutomaticModuleName() {
		return getSimple("Automatic-Module-Name");
	}

	String getBundleVersion() {
		return getSimple("Bundle-Version");
	}

	void setBundleVersion(String value) {
		putSimple("Bundle-Version", value);
	}

	String getBundleVendor() {
		return getSimple("Bundle-Vendor");
	}

	void setBundleVendor(String value) {
		putSimple("Bundle-Vendor", value);
	}

	String getActivationPolicy() {
		return getSimple("Bundle-ActivationPolicy");
	}

	void setLazyActivationPolicy() {
		putSimple("Bundle-ActivationPolicy", "lazy");
	}

	/**
	 * Returns the fragment host, or {@code null} if no fragment host is
	 * defined.
	 */
	ParameterValue getFragmentHost() {
		return firstValue("Fragment-Host");
	}

	/**
	 * Returns {@code true} if the 'unpack' flag must be set (used by features).
	 */
	boolean getNeedUnpack() {
		ParameterValue value = firstValue("Eclipse-BundleShape");
		if (value != null && value.getValue() != null && value.getValue().equals("dir")) {
			return true;
		}

		return false;
	}

	String[] getBinaryInclude() {
		return safeValueList("Binary-Include");
	}

	private static final String MANIFEST_VERSION = "Manifest-Version";

	void write(File mfFile) throws IOException {
		// calculate the order of the manifest entries
		if (referenceFile != null) {
			calculateOrder();
		}

		// always provide a manifest version
		ManifestAttribute mfVer = attributes.get(MANIFEST_VERSION);
		if (mfVer == null) {
			mfVer = new ManifestAttribute(MANIFEST_VERSION, "1.0");
			attributes.put(MANIFEST_VERSION, mfVer);
		}
		mfVer.order = Integer.MIN_VALUE;

		// sort the manifest entries
		List<ManifestAttribute> sorted = new ArrayList<>(attributes.values());
		Collections.sort(sorted, new Comparator<ManifestAttribute>() {

			@Override
			public int compare(ManifestAttribute a1, ManifestAttribute a2) {
				if (a1.order < a2.order) {
					return -1;
				}
				if (a1.order > a2.order) {
					return 1;
				}
				return a1.name.compareTo(a2.name);
			}
		});

		// write the manifest
		Writer ps = new FileWriter(mfFile);
		try {
			for (ManifestAttribute mf : sorted) {
				writeAttribute(mf.name, mf.values, ps);
			}
		} finally {
			ps.close();
		}
	}

	private static void writeAttribute(String name, ParameterValue[] value, Writer ps) throws IOException {
		ps.write(name);
		ps.write(": ");
		boolean firstLine = true;
		for (ParameterValue pv : value) {
			if (firstLine) {
				firstLine = false;
			} else {
				ps.write(",\n ");
			}
			pv.write(ps);
		}
		ps.write('\n');
	}

	private void calculateOrder() {
		List<String> lines = new ArrayList<>();
		try {
			LineNumberReader r = new LineNumberReader(new FileReader(referenceFile));
			try {
				String line;
				while ((line = r.readLine()) != null) {
					lines.add(line);
				}
			} finally {
				r.close();
			}
		} catch (Exception e) {
			Activator.log(IStatus.ERROR, "cannot read " + referenceFile, e);
			return;
		}

		int index = 0;
		for (String line : lines) {
			for (ManifestAttribute mf : attributes.values()) {
				if (line.startsWith(mf.name + ':')) {
					mf.order = index;
					break;
				}
			}
			++index;
		}
	}

	public boolean migrateUnpackInformation() {
		if (getBoolean("Unpack")) {
			putSimple("Eclipse-BundleShape", "dir");
			attributes.remove("Unpack");
			return true;
		}
		return false;
	}

	public ParameterValue getBuddyPolicy() {
		return firstValue("Eclipse-BuddyPolicy");
	}

	public ParameterValue[] getBuddyRegistrations() {
		return safeList("Eclipse-RegisterBuddy");
	}

}
