/*
 * Copyright (C) 2009, Google Inc.
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.transport;

import java.io.Serializable;
import java.net.URISyntaxException;
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 org.eclipse.jgit.lib.Config;

/**
 * A remembered remote repository, including URLs and RefSpecs.
 * <p>
 * A remote configuration remembers one or more URLs for a frequently accessed
 * remote repository as well as zero or more fetch and push specifications
 * describing how refs should be transferred between this repository and the
 * remote repository.
 */
public class RemoteConfig implements Serializable {
	private static final long serialVersionUID = 1L;

	private static final String SECTION = "remote"; //$NON-NLS-1$

	private static final String KEY_URL = "url"; //$NON-NLS-1$

	private static final String KEY_PUSHURL = "pushurl"; //$NON-NLS-1$

	private static final String KEY_FETCH = "fetch"; //$NON-NLS-1$

	private static final String KEY_PUSH = "push"; //$NON-NLS-1$

	private static final String KEY_UPLOADPACK = "uploadpack"; //$NON-NLS-1$

	private static final String KEY_RECEIVEPACK = "receivepack"; //$NON-NLS-1$

	private static final String KEY_TAGOPT = "tagopt"; //$NON-NLS-1$

	private static final String KEY_MIRROR = "mirror"; //$NON-NLS-1$

	private static final String KEY_TIMEOUT = "timeout"; //$NON-NLS-1$

	private static final String KEY_INSTEADOF = "insteadof"; //$NON-NLS-1$

	private static final String KEY_PUSHINSTEADOF = "pushinsteadof"; //$NON-NLS-1$

	private static final boolean DEFAULT_MIRROR = false;

	/** Default value for {@link #getUploadPack()} if not specified. */
	public static final String DEFAULT_UPLOAD_PACK = "git-upload-pack"; //$NON-NLS-1$

	/** Default value for {@link #getReceivePack()} if not specified. */
	public static final String DEFAULT_RECEIVE_PACK = "git-receive-pack"; //$NON-NLS-1$

	/**
	 * Parse all remote blocks in an existing configuration file, looking for
	 * remotes configuration.
	 *
	 * @param rc
	 *            the existing configuration to get the remote settings from.
	 *            The configuration must already be loaded into memory.
	 * @return all remotes configurations existing in provided repository
	 *         configuration. Returned configurations are ordered
	 *         lexicographically by names.
	 * @throws java.net.URISyntaxException
	 *             one of the URIs within the remote's configuration is invalid.
	 */
	public static List<RemoteConfig> getAllRemoteConfigs(Config rc)
			throws URISyntaxException {
		final List<String> names = new ArrayList<>(rc
				.getSubsections(SECTION));
		Collections.sort(names);

		final List<RemoteConfig> result = new ArrayList<>(names
				.size());
		for (String name : names)
			result.add(new RemoteConfig(rc, name));
		return result;
	}

	private String name;

	private List<URIish> uris;

	private List<URIish> pushURIs;

	private List<RefSpec> fetch;

	private List<RefSpec> push;

	private String uploadpack;

	private String receivepack;

	private TagOpt tagopt;

	private boolean mirror;

	private int timeout;

	/**
	 * Parse a remote block from an existing configuration file.
	 * <p>
	 * This constructor succeeds even if the requested remote is not defined
	 * within the supplied configuration file. If that occurs then there will be
	 * no URIs and no ref specifications known to the new instance.
	 *
	 * @param rc
	 *            the existing configuration to get the remote settings from.
	 *            The configuration must already be loaded into memory.
	 * @param remoteName
	 *            subsection key indicating the name of this remote.
	 * @throws java.net.URISyntaxException
	 *             one of the URIs within the remote's configuration is invalid.
	 */
	public RemoteConfig(Config rc, String remoteName)
			throws URISyntaxException {
		name = remoteName;

		String[] vlst;
		String val;

		vlst = rc.getStringList(SECTION, name, KEY_URL);
		Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
		uris = new ArrayList<>(vlst.length);
		for (String s : vlst) {
			uris.add(new URIish(replaceUri(s, insteadOf)));
		}
		String[] plst = rc.getStringList(SECTION, name, KEY_PUSHURL);
		pushURIs = new ArrayList<>(plst.length);
		for (String s : plst) {
			pushURIs.add(new URIish(s));
		}
		if (pushURIs.isEmpty()) {
			// Would default to the uris. If we have pushinsteadof, we must
			// supply rewritten push uris.
			Map<String, String> pushInsteadOf = getReplacements(rc,
					KEY_PUSHINSTEADOF);
			if (!pushInsteadOf.isEmpty()) {
				for (String s : vlst) {
					String replaced = replaceUri(s, pushInsteadOf);
					if (!s.equals(replaced)) {
						pushURIs.add(new URIish(replaced));
					}
				}
			}
		}
		fetch = rc.getRefSpecs(SECTION, name, KEY_FETCH);
		push = rc.getRefSpecs(SECTION, name, KEY_PUSH);
		val = rc.getString(SECTION, name, KEY_UPLOADPACK);
		if (val == null) {
			val = DEFAULT_UPLOAD_PACK;
		}
		uploadpack = val;

		val = rc.getString(SECTION, name, KEY_RECEIVEPACK);
		if (val == null) {
			val = DEFAULT_RECEIVE_PACK;
		}
		receivepack = val;

		try {
			val = rc.getString(SECTION, name, KEY_TAGOPT);
			tagopt = TagOpt.fromOption(val);
		} catch (IllegalArgumentException e) {
			// C git silently ignores invalid tagopt values.
			tagopt = TagOpt.AUTO_FOLLOW;
		}
		mirror = rc.getBoolean(SECTION, name, KEY_MIRROR, DEFAULT_MIRROR);
		timeout = rc.getInt(SECTION, name, KEY_TIMEOUT, 0);
	}

	/**
	 * Update this remote's definition within the configuration.
	 *
	 * @param rc
	 *            the configuration file to store ourselves into.
	 */
	public void update(Config rc) {
		final List<String> vlst = new ArrayList<>();

		vlst.clear();
		for (URIish u : getURIs())
			vlst.add(u.toPrivateString());
		rc.setStringList(SECTION, getName(), KEY_URL, vlst);

		vlst.clear();
		for (URIish u : getPushURIs())
			vlst.add(u.toPrivateString());
		rc.setStringList(SECTION, getName(), KEY_PUSHURL, vlst);

		vlst.clear();
		for (RefSpec u : getFetchRefSpecs())
			vlst.add(u.toString());
		rc.setStringList(SECTION, getName(), KEY_FETCH, vlst);

		vlst.clear();
		for (RefSpec u : getPushRefSpecs())
			vlst.add(u.toString());
		rc.setStringList(SECTION, getName(), KEY_PUSH, vlst);

		set(rc, KEY_UPLOADPACK, getUploadPack(), DEFAULT_UPLOAD_PACK);
		set(rc, KEY_RECEIVEPACK, getReceivePack(), DEFAULT_RECEIVE_PACK);
		set(rc, KEY_TAGOPT, getTagOpt().option(), TagOpt.AUTO_FOLLOW.option());
		set(rc, KEY_MIRROR, mirror, DEFAULT_MIRROR);
		set(rc, KEY_TIMEOUT, timeout, 0);
	}

	private void set(final Config rc, final String key,
			final String currentValue, final String defaultValue) {
		if (defaultValue.equals(currentValue))
			unset(rc, key);
		else
			rc.setString(SECTION, getName(), key, currentValue);
	}

	private void set(final Config rc, final String key,
			final boolean currentValue, final boolean defaultValue) {
		if (defaultValue == currentValue)
			unset(rc, key);
		else
			rc.setBoolean(SECTION, getName(), key, currentValue);
	}

	private void set(final Config rc, final String key, final int currentValue,
			final int defaultValue) {
		if (defaultValue == currentValue)
			unset(rc, key);
		else
			rc.setInt(SECTION, getName(), key, currentValue);
	}

	private void unset(Config rc, String key) {
		rc.unset(SECTION, getName(), key);
	}

	private Map<String, String> getReplacements(final Config config,
			final String keyName) {
		final Map<String, String> replacements = new HashMap<>();
		for (String url : config.getSubsections(KEY_URL))
			for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
				replacements.put(insteadOf, url);
		return replacements;
	}

	private String replaceUri(final String uri,
			final Map<String, String> replacements) {
		if (replacements.isEmpty()) {
			return uri;
		}
		Entry<String, String> match = null;
		for (Entry<String, String> replacement : replacements.entrySet()) {
			// Ignore current entry if not longer than previous match
			if (match != null
					&& match.getKey().length() > replacement.getKey()
							.length()) {
				continue;
			}
			if (!uri.startsWith(replacement.getKey())) {
				continue;
			}
			match = replacement;
		}
		if (match != null) {
			return match.getValue() + uri.substring(match.getKey().length());
		}
		return uri;
	}

	/**
	 * Get the local name this remote configuration is recognized as.
	 *
	 * @return name assigned by the user to this configuration block.
	 */
	public String getName() {
		return name;
	}

	/**
	 * Get all configured URIs under this remote.
	 *
	 * @return the set of URIs known to this remote.
	 */
	public List<URIish> getURIs() {
		return Collections.unmodifiableList(uris);
	}

	/**
	 * Add a new URI to the end of the list of URIs.
	 *
	 * @param toAdd
	 *            the new URI to add to this remote.
	 * @return true if the URI was added; false if it already exists.
	 */
	public boolean addURI(URIish toAdd) {
		if (uris.contains(toAdd))
			return false;
		return uris.add(toAdd);
	}

	/**
	 * Remove a URI from the list of URIs.
	 *
	 * @param toRemove
	 *            the URI to remove from this remote.
	 * @return true if the URI was added; false if it already exists.
	 */
	public boolean removeURI(URIish toRemove) {
		return uris.remove(toRemove);
	}

	/**
	 * Get all configured push-only URIs under this remote.
	 *
	 * @return the set of URIs known to this remote.
	 */
	public List<URIish> getPushURIs() {
		return Collections.unmodifiableList(pushURIs);
	}

	/**
	 * Add a new push-only URI to the end of the list of URIs.
	 *
	 * @param toAdd
	 *            the new URI to add to this remote.
	 * @return true if the URI was added; false if it already exists.
	 */
	public boolean addPushURI(URIish toAdd) {
		if (pushURIs.contains(toAdd))
			return false;
		return pushURIs.add(toAdd);
	}

	/**
	 * Remove a push-only URI from the list of URIs.
	 *
	 * @param toRemove
	 *            the URI to remove from this remote.
	 * @return true if the URI was added; false if it already exists.
	 */
	public boolean removePushURI(URIish toRemove) {
		return pushURIs.remove(toRemove);
	}

	/**
	 * Remembered specifications for fetching from a repository.
	 *
	 * @return set of specs used by default when fetching.
	 */
	public List<RefSpec> getFetchRefSpecs() {
		return Collections.unmodifiableList(fetch);
	}

	/**
	 * Add a new fetch RefSpec to this remote.
	 *
	 * @param s
	 *            the new specification to add.
	 * @return true if the specification was added; false if it already exists.
	 */
	public boolean addFetchRefSpec(RefSpec s) {
		if (fetch.contains(s))
			return false;
		return fetch.add(s);
	}

	/**
	 * Override existing fetch specifications with new ones.
	 *
	 * @param specs
	 *            list of fetch specifications to set. List is copied, it can be
	 *            modified after this call.
	 */
	public void setFetchRefSpecs(List<RefSpec> specs) {
		fetch.clear();
		fetch.addAll(specs);
	}

	/**
	 * Override existing push specifications with new ones.
	 *
	 * @param specs
	 *            list of push specifications to set. List is copied, it can be
	 *            modified after this call.
	 */
	public void setPushRefSpecs(List<RefSpec> specs) {
		push.clear();
		push.addAll(specs);
	}

	/**
	 * Remove a fetch RefSpec from this remote.
	 *
	 * @param s
	 *            the specification to remove.
	 * @return true if the specification existed and was removed.
	 */
	public boolean removeFetchRefSpec(RefSpec s) {
		return fetch.remove(s);
	}

	/**
	 * Remembered specifications for pushing to a repository.
	 *
	 * @return set of specs used by default when pushing.
	 */
	public List<RefSpec> getPushRefSpecs() {
		return Collections.unmodifiableList(push);
	}

	/**
	 * Add a new push RefSpec to this remote.
	 *
	 * @param s
	 *            the new specification to add.
	 * @return true if the specification was added; false if it already exists.
	 */
	public boolean addPushRefSpec(RefSpec s) {
		if (push.contains(s))
			return false;
		return push.add(s);
	}

	/**
	 * Remove a push RefSpec from this remote.
	 *
	 * @param s
	 *            the specification to remove.
	 * @return true if the specification existed and was removed.
	 */
	public boolean removePushRefSpec(RefSpec s) {
		return push.remove(s);
	}

	/**
	 * Override for the location of 'git-upload-pack' on the remote system.
	 * <p>
	 * This value is only useful for an SSH style connection, where Git is
	 * asking the remote system to execute a program that provides the necessary
	 * network protocol.
	 *
	 * @return location of 'git-upload-pack' on the remote system. If no
	 *         location has been configured the default of 'git-upload-pack' is
	 *         returned instead.
	 */
	public String getUploadPack() {
		return uploadpack;
	}

	/**
	 * Override for the location of 'git-receive-pack' on the remote system.
	 * <p>
	 * This value is only useful for an SSH style connection, where Git is
	 * asking the remote system to execute a program that provides the necessary
	 * network protocol.
	 *
	 * @return location of 'git-receive-pack' on the remote system. If no
	 *         location has been configured the default of 'git-receive-pack' is
	 *         returned instead.
	 */
	public String getReceivePack() {
		return receivepack;
	}

	/**
	 * Get the description of how annotated tags should be treated during fetch.
	 *
	 * @return option indicating the behavior of annotated tags in fetch.
	 */
	public TagOpt getTagOpt() {
		return tagopt;
	}

	/**
	 * Set the description of how annotated tags should be treated on fetch.
	 *
	 * @param option
	 *            method to use when handling annotated tags.
	 */
	public void setTagOpt(TagOpt option) {
		tagopt = option != null ? option : TagOpt.AUTO_FOLLOW;
	}

	/**
	 * Whether pushing to the remote automatically deletes remote refs which
	 * don't exist on the source side.
	 *
	 * @return true if pushing to the remote automatically deletes remote refs
	 *         which don't exist on the source side.
	 */
	public boolean isMirror() {
		return mirror;
	}

	/**
	 * Set the mirror flag to automatically delete remote refs.
	 *
	 * @param m
	 *            true to automatically delete remote refs during push.
	 */
	public void setMirror(boolean m) {
		mirror = m;
	}

	/**
	 * Get timeout (in seconds) before aborting an IO operation.
	 *
	 * @return timeout (in seconds) before aborting an IO operation.
	 */
	public int getTimeout() {
		return timeout;
	}

	/**
	 * Set the timeout before willing to abort an IO call.
	 *
	 * @param seconds
	 *            number of seconds to wait (with no data transfer occurring)
	 *            before aborting an IO read or write operation with this
	 *            remote.  A timeout of 0 will block indefinitely.
	 */
	public void setTimeout(int seconds) {
		timeout = seconds;
	}
}
