/*
 * Copyright (C) 2010, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.transport;

import java.util.Arrays;

import org.eclipse.jgit.internal.JGitText;

/**
 * A credential requested from a
 * {@link org.eclipse.jgit.transport.CredentialsProvider}.
 *
 * Most users should work with the specialized subclasses:
 * <ul>
 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Username} for
 * usernames</li>
 * <li>{@link org.eclipse.jgit.transport.CredentialItem.Password} for
 * passwords</li>
 * <li>{@link org.eclipse.jgit.transport.CredentialItem.StringType} for other
 * general string information</li>
 * <li>{@link org.eclipse.jgit.transport.CredentialItem.CharArrayType} for other
 * general secret information</li>
 * </ul>
 *
 * This class is not thread-safe. Applications should construct their own
 * instance for each use, as the value is held within the CredentialItem object.
 */
public abstract class CredentialItem {
	private final String promptText;

	private final boolean valueSecure;

	/**
	 * Initialize a prompt.
	 *
	 * @param promptText
	 *            prompt to display to the user alongside of the input field.
	 *            Should be sufficient text to indicate what to supply for this
	 *            item.
	 * @param maskValue
	 *            true if the value should be masked from displaying during
	 *            input. This should be true for passwords and other secrets,
	 *            false for names and other public data.
	 */
	public CredentialItem(String promptText, boolean maskValue) {
		this.promptText = promptText;
		this.valueSecure = maskValue;
	}

	/**
	 * Get prompt to display to the user.
	 *
	 * @return prompt to display to the user.
	 */
	public String getPromptText() {
		return promptText;
	}

	/**
	 * Whether the value should be masked when entered.
	 *
	 * @return true if the value should be masked when entered.
	 */
	public boolean isValueSecure() {
		return valueSecure;
	}

	/**
	 * Clear the stored value, destroying it as much as possible.
	 */
	public abstract void clear();

	/**
	 * An item whose value is stored as a string.
	 *
	 * When working with secret data, consider {@link CharArrayType} instead, as
	 * the internal members of the array can be cleared, reducing the chances
	 * that the password is left in memory after authentication is completed.
	 */
	public static class StringType extends CredentialItem {
		private String value;

		/**
		 * Initialize a prompt for a single string.
		 *
		 * @param promptText
		 *            prompt to display to the user alongside of the input
		 *            field. Should be sufficient text to indicate what to
		 *            supply for this item.
		 * @param maskValue
		 *            true if the value should be masked from displaying during
		 *            input. This should be true for passwords and other
		 *            secrets, false for names and other public data.
		 */
		public StringType(String promptText, boolean maskValue) {
			super(promptText, maskValue);
		}

		@Override
		public void clear() {
			value = null;
		}

		/** @return the current value */
		public String getValue() {
			return value;
		}

		/**
		 *
		 * @param newValue
		 */
		public void setValue(String newValue) {
			value = newValue;
		}
	}

	/** An item whose value is stored as a char[] and is therefore clearable. */
	public static class CharArrayType extends CredentialItem {
		private char[] value;

		/**
		 * Initialize a prompt for a secure value stored in a character array.
		 *
		 * @param promptText
		 *            prompt to display to the user alongside of the input
		 *            field. Should be sufficient text to indicate what to
		 *            supply for this item.
		 * @param maskValue
		 *            true if the value should be masked from displaying during
		 *            input. This should be true for passwords and other
		 *            secrets, false for names and other public data.
		 */
		public CharArrayType(String promptText, boolean maskValue) {
			super(promptText, maskValue);
		}

		/** Destroys the current value, clearing the internal array. */
		@Override
		public void clear() {
			if (value != null) {
				Arrays.fill(value, (char) 0);
				value = null;
			}
		}

		/**
		 * Get the current value.
		 *
		 * The returned array will be cleared out when {@link #clear()} is
		 * called. Callers that need the array elements to survive should delay
		 * invoking {@code clear()} until the value is no longer necessary.
		 *
		 * @return the current value array. The actual internal array is
		 *         returned, reducing the number of copies present in memory.
		 */
		public char[] getValue() {
			return value;
		}

		/**
		 * Set the new value, clearing the old value array.
		 *
		 * @param newValue
		 *            if not null, the array is copied.
		 */
		public void setValue(char[] newValue) {
			clear();

			if (newValue != null) {
				value = new char[newValue.length];
				System.arraycopy(newValue, 0, value, 0, newValue.length);
			}
		}

		/**
		 * Set the new value, clearing the old value array.
		 *
		 * @param newValue
		 *            the new internal array. The array is <b>NOT</b> copied.
		 */
		public void setValueNoCopy(char[] newValue) {
			clear();
			value = newValue;
		}
	}

	/** An item whose value is a boolean choice, presented as Yes/No. */
	public static class YesNoType extends CredentialItem {
		private boolean value;

		/**
		 * Initialize a prompt for a single boolean answer.
		 *
		 * @param promptText
		 *            prompt to display to the user alongside of the input
		 *            field. Should be sufficient text to indicate what to
		 *            supply for this item.
		 */
		public YesNoType(String promptText) {
			super(promptText, false);
		}

		@Override
		public void clear() {
			value = false;
		}

		/** @return the current value */
		public boolean getValue() {
			return value;
		}

		/**
		 * Set the new value.
		 *
		 * @param newValue
		 */
		public void setValue(boolean newValue) {
			value = newValue;
		}
	}

	/** An advice message presented to the user, with no response required. */
	public static class InformationalMessage extends CredentialItem {
		/**
		 * Initialize an informational message.
		 *
		 * @param messageText
		 *            message to display to the user.
		 */
		public InformationalMessage(String messageText) {
			super(messageText, false);
		}

		@Override
		public void clear() {
			// Nothing to clear.
		}
	}

	/** Prompt for a username, which is not masked on input. */
	public static class Username extends StringType {
		/** Initialize a new username item, with a default username prompt. */
		public Username() {
			super(JGitText.get().credentialUsername, false);
		}
	}

	/** Prompt for a password, which is masked on input. */
	public static class Password extends CharArrayType {
		/** Initialize a new password item, with a default password prompt. */
		public Password() {
			super(JGitText.get().credentialPassword, true);
		}

		/**
		 * Initialize a new password item, with given prompt.
		 *
		 * @param msg
		 *            prompt message
		 */
		public Password(String msg) {
			super(msg, true);
		}
	}
}
