/*-
 * Copyright (C) 2019, 2020 Salesforce 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.gpg.bc.internal;

import java.net.URISyntaxException;
import java.nio.file.Path;
import java.text.MessageFormat;

import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.transport.CredentialItem.CharArrayType;
import org.eclipse.jgit.transport.CredentialItem.InformationalMessage;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;

/**
 * Prompts for a passphrase and caches it until {@link #clear() cleared}.
 * <p>
 * Implements {@link AutoCloseable} so it can be used within a
 * try-with-resources block.
 * </p>
 */
class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable {

	private CharArrayType passphrase;

	private CredentialsProvider credentialsProvider;

	public BouncyCastleGpgKeyPassphrasePrompt(
			CredentialsProvider credentialsProvider) {
		this.credentialsProvider = credentialsProvider;
	}

	/**
	 * Clears any cached passphrase
	 */
	public void clear() {
		if (passphrase != null) {
			passphrase.clear();
			passphrase = null;
		}
	}

	@Override
	public void close() {
		clear();
	}

	private URIish createURI(Path keyLocation) throws URISyntaxException {
		return new URIish(keyLocation.toUri().toString());
	}

	/**
	 * Prompts use for a passphrase unless one was cached from a previous
	 * prompt.
	 *
	 * @param keyFingerprint
	 *            the fingerprint to show to the user during prompting
	 * @param keyLocation
	 *            the location the key was loaded from
	 * @return the passphrase (maybe <code>null</code>)
	 * @throws PGPException
	 * @throws CanceledException
	 *             in case passphrase was not entered by user
	 * @throws URISyntaxException
	 * @throws UnsupportedCredentialItem
	 */
	public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
			throws PGPException, CanceledException, UnsupportedCredentialItem,
			URISyntaxException {
		if (passphrase == null) {
			passphrase = new CharArrayType(BCText.get().credentialPassphrase,
					true);
		}

		if (credentialsProvider == null) {
			throw new PGPException(BCText.get().gpgNoCredentialsProvider);
		}

		if (passphrase.getValue() == null
				&& !credentialsProvider.get(createURI(keyLocation),
						new InformationalMessage(
								MessageFormat.format(BCText.get().gpgKeyInfo,
										Hex.toHexString(keyFingerprint))),
						passphrase)) {
			throw new CanceledException(BCText.get().gpgSigningCancelled);
		}
		return passphrase.getValue();
	}

	/**
	 * Determines whether a passphrase was already obtained.
	 *
	 * @return {@code true} if a passphrase is already set, {@code false}
	 *         otherwise
	 */
	public boolean hasPassphrase() {
		return passphrase != null && passphrase.getValue() != null;
	}
}
