/*=============================================================================#
 # Copyright (c) 2009, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.server;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.server.srvext.ServerAuthMethod;


@NonNullByDefault
public final class ServerLogin implements Serializable {
	
	
	private static final long serialVersionUID= -596748668244272719L;
	
	
	private long id;
	
	private @Nullable Key pubkey;
	
	private Callback @Nullable [] callbacks;
	
	
	public ServerLogin(final long id, final @Nullable Key pubkey, final ImList<Callback> callbacks) {
		this.id= id;
		this.pubkey= pubkey;
		this.callbacks= callbacks.toArray(new @NonNull Callback[callbacks.size()]);
	}
	
	/** for Serializable */
	public ServerLogin() {
	}
	
	
	public long getId() {
		return this.id;
	}
	
	/**
	 * The callback items which should be handled by the client.
	 * 
	 * @return an array with all callback objects
	 * @see CallbackHandler
	 */
	public ImList<Callback> getCallbacks() {
		final var callbacks= this.callbacks;
		if (callbacks == null) {
			throw new IllegalStateException("no longer valid");
		}
		return ImCollections.newList(callbacks);
	}
	
	/**
	 * Must be called by the client to create login data for authentification
	 * when connecting to server via {@link Server#start(ServerLogin, String[])}
	 * or {@link Server#connect(ServerLogin)}.
	 * 
	 * @return the login data prepared to send to the server
	 * @throws RjException when creating login data failed
	 */
	public ServerLogin createAnswer() throws RjException {
		try {
			final var callbacks= nonNullAssert(this.callbacks);
			final var answerCallbacks= new @NonNull Callback[callbacks.length];
			System.arraycopy(callbacks, 0, answerCallbacks, 0, callbacks.length);
			final Key pubkey= this.pubkey;
			if (pubkey != null) {
				process(answerCallbacks, Cipher.ENCRYPT_MODE, pubkey);
			}
			return new ServerLogin(this.id, null, ImCollections.newList(answerCallbacks));
		}
		catch (final Exception e) {
			throw new RjException("An error occurred when creating login data.", e);
		}
	}
	
	/**
	 * Is called by server to decrypt data. By default it is called in
	 * {@link ServerAuthMethod#performLogin(ServerLogin)}.
	 * 
	 * @param privateKey the key to decrypt the data
	 * @throws RjException when processing login data failed
	 */
	public void readAnswer(final @Nullable Key privateKey) throws RjException {
		try {
			final var callbacks= nonNullAssert(this.callbacks);
			if (privateKey != null) {
				process(callbacks, Cipher.DECRYPT_MODE, privateKey);
			}
		}
		catch (final Exception e) {
			throw new RjException("An error occurred when processing login data.", e);
		}
	}
	
	private void process(final Callback[] callbacks, final int mode, final Key key) throws Exception {
		final Cipher with= Cipher.getInstance("RSA");
		with.init(mode, key);
		final Charset charset= StandardCharsets.UTF_8;
		
		for (int i= 0; i < callbacks.length; i++) {
			if (callbacks[i] instanceof PasswordCallback) {
				final PasswordCallback c= (PasswordCallback) callbacks[i];
				final char[] orgPassword= c.getPassword();
				if (orgPassword != null) {
					final byte[] orgBytes;
					if (mode == Cipher.ENCRYPT_MODE) {
						orgBytes= charset.encode(CharBuffer.wrap(orgPassword)).array();
					}
					else {
						orgBytes= new byte[orgPassword.length];
						for (int j= 0; j < orgBytes.length; j++) {
							orgBytes[j]= (byte) orgPassword[j];
						}
					}
					final byte[] encBytes= with.doFinal(orgBytes);
					final char[] encPassword;
					if (mode == Cipher.ENCRYPT_MODE) {
						encPassword= new char[encBytes.length];
						for (int j= 0; j < encPassword.length; j++) {
							encPassword[j]= (char) encBytes[j];
						}
					}
					else {
						encPassword= charset.decode(ByteBuffer.wrap(encBytes)).array();
					}
					
					if (mode == Cipher.ENCRYPT_MODE) {
						final PasswordCallback copy= new PasswordCallback(c.getPrompt(), c.isEchoOn());
						copy.setPassword(encPassword);
						callbacks[i]= copy;
					}
					else {
						c.clearPassword();
						c.setPassword(encPassword);
					}
					
					Arrays.fill(orgBytes, (byte)0);
					Arrays.fill(orgPassword, (char)0);
					Arrays.fill(encBytes, (byte)0);
					Arrays.fill(encPassword, (char)0);
				}
				continue;
			}
		}
	}
	
	/**
	 * Clear data, especially the password.
	 */
	public void clearData() {
		this.pubkey= null;
		final var callbacks= this.callbacks;
		if (callbacks != null) {
			this.callbacks= null;
			for (int i= 0; i < callbacks.length; i++) {
				if (callbacks[i] instanceof PasswordCallback) {
					((PasswordCallback)callbacks[i]).clearPassword();
				}
			}
		}
	}
	
}
