/*
 * 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.internal.transport.ssh.jsch;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;

import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;

/**
 * A JSch {@link com.jcraft.jsch.UserInfo} adapter for a
 * {@link org.eclipse.jgit.transport.CredentialsProvider}.
 */
public class CredentialsProviderUserInfo implements UserInfo,
		UIKeyboardInteractive {
	private final URIish uri;

	private final CredentialsProvider provider;

	private String password;

	private String passphrase;

	/**
	 * Wrap a CredentialsProvider to make it suitable for use with JSch.
	 *
	 * @param session
	 *            the JSch session this UserInfo will support authentication on.
	 * @param credentialsProvider
	 *            the provider that will perform the authentication.
	 */
	public CredentialsProviderUserInfo(Session session,
			CredentialsProvider credentialsProvider) {
		this.uri = createURI(session);
		this.provider = credentialsProvider;
	}

	private static URIish createURI(Session session) {
		URIish uri = new URIish();
		uri = uri.setScheme("ssh"); //$NON-NLS-1$
		uri = uri.setUser(session.getUserName());
		uri = uri.setHost(session.getHost());
		uri = uri.setPort(session.getPort());
		return uri;
	}

	@Override
	public String getPassword() {
		return password;
	}

	@Override
	public String getPassphrase() {
		return passphrase;
	}

	@Override
	public boolean promptPassphrase(String msg) {
		CredentialItem.StringType v = newPrompt(msg);
		if (provider.get(uri, v)) {
			passphrase = v.getValue();
			return true;
		}
		passphrase = null;
		return false;
	}

	@Override
	public boolean promptPassword(String msg) {
		CredentialItem.Password p = new CredentialItem.Password(msg);
		if (provider.get(uri, p)) {
			password = new String(p.getValue());
			return true;
		}
		password = null;
		return false;
	}

	private CredentialItem.StringType newPrompt(String msg) {
		return new CredentialItem.StringType(msg, true);
	}

	@Override
	public boolean promptYesNo(String msg) {
		CredentialItem.YesNoType v = new CredentialItem.YesNoType(msg);
		return provider.get(uri, v) && v.getValue();
	}

	@Override
	public void showMessage(String msg) {
		provider.get(uri, new CredentialItem.InformationalMessage(msg));
	}

	@Override
	public String[] promptKeyboardInteractive(String destination, String name,
			String instruction, String[] prompt, boolean[] echo) {
		CredentialItem.StringType[] v = new CredentialItem.StringType[prompt.length];
		for (int i = 0; i < prompt.length; i++)
			v[i] = new CredentialItem.StringType(prompt[i], !echo[i]);

		List<CredentialItem> items = new ArrayList<>();
		if (instruction != null && instruction.length() > 0)
			items.add(new CredentialItem.InformationalMessage(instruction));
		items.addAll(Arrays.asList(v));

		if (!provider.get(uri, items))
			return null; // cancel

		String[] result = new String[v.length];
		for (int i = 0; i < v.length; i++)
			result[i] = v[i].getValue();
		return result;
	}
}
