/*
 * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> 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.sshd;

import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS;

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

import org.apache.sshd.common.AttributeRepository.AttributeKey;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.session.SessionContext;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;

/**
 * A bridge from sshd's {@link FilePasswordProvider} to our per-session
 * {@link KeyPasswordProvider} API.
 */
public class PasswordProviderWrapper implements FilePasswordProvider {

	private static final AttributeKey<PerSessionState> STATE = new AttributeKey<>();

	private static class PerSessionState {

		Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();

		KeyPasswordProvider delegate;

	}

	private final Supplier<KeyPasswordProvider> factory;

	/**
	 * Creates a new {@link PasswordProviderWrapper}.
	 *
	 * @param factory
	 *            to use to create per-session {@link KeyPasswordProvider}s
	 */
	public PasswordProviderWrapper(
			@NonNull Supplier<KeyPasswordProvider> factory) {
		this.factory = factory;
	}

	private PerSessionState getState(SessionContext context) {
		PerSessionState state = context.getAttribute(STATE);
		if (state == null) {
			state = new PerSessionState();
			state.delegate = factory.get();
			state.delegate.setAttempts(
					PASSWORD_PROMPTS.getRequiredDefault().intValue());
			context.setAttribute(STATE, state);
		}
		return state;
	}

	@Override
	public String getPassword(SessionContext session, NamedResource resource,
			int attemptIndex) throws IOException {
		String key = resource.getName();
		PerSessionState state = getState(session);
		int attempt = state.counts
				.computeIfAbsent(key, k -> new AtomicInteger()).get();
		char[] passphrase = state.delegate.getPassphrase(toUri(key), attempt);
		if (passphrase == null) {
			return null;
		}
		try {
			return new String(passphrase);
		} finally {
			Arrays.fill(passphrase, '\000');
		}
	}

	@Override
	public ResourceDecodeResult handleDecodeAttemptResult(
			SessionContext session, NamedResource resource, int retryIndex,
			String password, Exception err)
			throws IOException, GeneralSecurityException {
		String key = resource.getName();
		PerSessionState state = getState(session);
		AtomicInteger count = state.counts.get(key);
		int numberOfAttempts = count == null ? 0 : count.incrementAndGet();
		ResourceDecodeResult result = null;
		try {
			if (state.delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
				result = ResourceDecodeResult.RETRY;
			} else {
				result = ResourceDecodeResult.TERMINATE;
			}
		} finally {
			if (result != ResourceDecodeResult.RETRY) {
				state.counts.remove(key);
			}
		}
		return result;
	}

	/**
	 * Creates a {@link URIish} from a given string. The
	 * {@link CredentialsProvider} uses uris as resource identifications.
	 *
	 * @param resourceKey
	 *            to convert
	 * @return the uri
	 */
	private URIish toUri(String resourceKey) {
		try {
			return new URIish(resourceKey);
		} catch (URISyntaxException e) {
			return new URIish().setPath(resourceKey); // Doesn't check!!
		}
	}

}
