/*******************************************************************************
 * Copyright (c) 2007, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *		compeople AG (Stefan Liebig) - various ongoing maintenance
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.artifact.repository.simple;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Dictionary;
import java.util.Hashtable;
import org.eclipse.core.runtime.URIUtil;
import org.osgi.framework.*;

public class Mapper {
	private Filter[] filters;
	private String[] outputStrings;

	private static final String REPOURL = "repoUrl"; //$NON-NLS-1$
	private static final String CLASSIFIER = "classifier"; //$NON-NLS-1$
	private static final String FORMAT = "format"; //$NON-NLS-1$
	private static final String ID = "id"; //$NON-NLS-1$
	private static final String VERSION = "version"; //$NON-NLS-1$

	public Mapper() {
		filters = new Filter[0];
		outputStrings = new String[0];
	}

	/**
	 * mapping rule: LDAP filter --> output value
	 * the more specific filters should be given first.
	 */
	public void initialize(BundleContext ctx, String[][] mappingRules) {
		filters = new Filter[mappingRules.length];
		outputStrings = new String[mappingRules.length];
		for (int i = 0; i < mappingRules.length; i++) {
			try {
				filters[i] = ctx.createFilter(mappingRules[i][0]);
				outputStrings[i] = mappingRules[i][1];
			} catch (InvalidSyntaxException e) {
				//TODO Neeed to process this
				e.printStackTrace();
			}
		}
	}

	public URI map(URI repositoryLocation, String classifier, String id, String version, String format) {
		String locationString = URIUtil.toUnencodedString(repositoryLocation);
		Dictionary<String, Object> values = new Hashtable<>(5);
		if (repositoryLocation != null)
			values.put(REPOURL, locationString);

		if (classifier != null)
			values.put(CLASSIFIER, classifier);

		if (id != null)
			values.put(ID, id);

		if (version != null)
			values.put(VERSION, version);

		if (format != null)
			values.put(FORMAT, format);

		for (int i = 0; i < filters.length; i++) {
			if (filters[i].match(values))
				return doReplacement(outputStrings[i], locationString, classifier, id, version, format);
		}
		return null;
	}

	private URI doReplacement(String pattern, String repoLocation, String classifier, String id, String version, String format) {
		try {
			// currently our mapping rules assume the repo URL is not "/" terminated. 
			// This may be the case for repoURLs in the root of a URL space e.g. root of a jar file or file:/c:/
			if (repoLocation.endsWith("/")) //$NON-NLS-1$
				repoLocation = repoLocation.substring(0, repoLocation.length() - 1);

			StringBuilder output = new StringBuilder(pattern);
			int index = 0;
			while (index < output.length()) {
				int beginning = output.indexOf("${", index); //$NON-NLS-1$
				if (beginning == -1)
					return URIUtil.fromString(output.toString());

				int end = output.indexOf("}", beginning); //$NON-NLS-1$
				if (end == -1)
					return URIUtil.fromString(pattern);

				String varName = output.substring(beginning + 2, end);
				String varValue = null;
				if (varName.equalsIgnoreCase(CLASSIFIER)) {
					varValue = classifier;
				} else if (varName.equalsIgnoreCase(ID)) {
					varValue = id;
				} else if (varName.equalsIgnoreCase(VERSION)) {
					varValue = version;
				} else if (varName.equalsIgnoreCase(REPOURL)) {
					varValue = repoLocation;
				} else if (varName.equalsIgnoreCase(FORMAT)) {
					varValue = format;
				}
				if (varValue == null)
					varValue = ""; //$NON-NLS-1$

				output.replace(beginning, end + 1, varValue);
				index = beginning + varValue.length();
			}
			return URIUtil.fromString(output.toString());
		} catch (URISyntaxException e) {
			return null;
		}
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < filters.length; i++) {
			result.append(filters[i]).append('-').append('>').append(outputStrings[i]).append('\n');
		}
		return result.toString();
	}

	public String[][] serialize() {
		String[][] result = new String[filters.length][2];
		for (int i = 0; i < filters.length; i++) {
			result[i][0] = filters[i].toString();
			result[i][1] = outputStrings[i];
		}
		return result;
	}
}
