/*
 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>,
 * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
 * 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.util.List;

import org.eclipse.jgit.errors.UnsupportedCredentialItem;

/**
 * Provide credentials for use in connecting to Git repositories.
 *
 * Implementors are strongly encouraged to support at least the minimal
 * {@link CredentialItem.Username} and {@link CredentialItem.Password} items.
 * More sophisticated implementors may implement additional types, such as
 * {@link CredentialItem.StringType}.
 *
 * CredentialItems are usually presented in bulk, allowing implementors to
 * combine them into a single UI widget and streamline the authentication
 * process for an end-user.
 *
 * @see UsernamePasswordCredentialsProvider
 */
public abstract class CredentialsProvider {
	private static volatile CredentialsProvider defaultProvider;

	/** @return the default credentials provider, or null. */
	public static CredentialsProvider getDefault() {
		return defaultProvider;
	}

	/**
	 * Set the default credentials provider.
	 *
	 * @param p
	 *            the new default provider, may be null to select no default.
	 */
	public static void setDefault(CredentialsProvider p) {
		defaultProvider = p;
	}

	/**
	 * Check if the provider is interactive with the end-user.
	 *
	 * An interactive provider may try to open a dialog box, or prompt for input
	 * on the terminal, and will wait for a user response. A non-interactive
	 * provider will either populate CredentialItems, or fail.
	 *
	 * @return {@code true} if the provider is interactive with the end-user.
	 */
	public abstract boolean isInteractive();

	/**
	 * Check if the provider can supply the necessary {@link CredentialItem}s.
	 *
	 * @param items
	 *            the items the application requires to complete authentication.
	 * @return {@code true} if this {@link CredentialsProvider} supports all of
	 *         the items supplied.
	 */
	public abstract boolean supports(CredentialItem... items);

	/**
	 * Ask for the credential items to be populated.
	 *
	 * @param uri
	 *            the URI of the remote resource that needs authentication.
	 * @param items
	 *            the items the application requires to complete authentication.
	 * @return {@code true} if the request was successful and values were
	 *         supplied; {@code false} if the user canceled the request and did
	 *         not supply all requested values.
	 * @throws UnsupportedCredentialItem
	 *             if one of the items supplied is not supported.
	 */
	public abstract boolean get(URIish uri, CredentialItem... items)
			throws UnsupportedCredentialItem;

	/**
	 * Ask for the credential items to be populated.
	 *
	 * @param uri
	 *            the URI of the remote resource that needs authentication.
	 * @param items
	 *            the items the application requires to complete authentication.
	 * @return {@code true} if the request was successful and values were
	 *         supplied; {@code false} if the user canceled the request and did
	 *         not supply all requested values.
	 * @throws UnsupportedCredentialItem
	 *             if one of the items supplied is not supported.
	 */
	public boolean get(URIish uri, List<CredentialItem> items)
			throws UnsupportedCredentialItem {
		return get(uri, items.toArray(new CredentialItem[items.size()]));
	}

	/**
	 * Reset the credentials provider for the given URI
	 *
	 * @param uri
	 */
	public void reset(URIish uri) {
		// default does nothing
	}
}
