/*=============================================================================#
 # Copyright (c) 2009, 2018 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 java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
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.rj.RjException;
import org.eclipse.statet.rj.server.srvext.ServerAuthMethod;


public final class ServerLogin implements Serializable {
	
	
	private static final long serialVersionUID= -596748668244272719L;
	
	
	private long id;
	
	private Key pubkey;
	
	private Callback[] callbacks;
	
	
	public ServerLogin() {
	}
	
	public ServerLogin(final long id, final Key pubkey, final Callback[] callbacks) {
		this.id= id;
		this.pubkey= pubkey;
		this.callbacks= callbacks;
	}
	
	
	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 Callback[] getCallbacks() {
		return this.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 {
			Callback[] copy;
			if (this.callbacks != null) {
				copy= new Callback[this.callbacks.length];
				System.arraycopy(this.callbacks, 0, copy, 0, this.callbacks.length);
				if (this.pubkey != null) {
					process(copy, Cipher.ENCRYPT_MODE, this.pubkey);
				}
			}
			else {
				copy= null;
			}
			return new ServerLogin(this.id, null, copy);
		}
		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 Key privateKey) throws RjException {
		try {
			if (privateKey != null) {
				process(this.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= Charset.forName("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;
		if (this.callbacks != null) {
			for (int i= 0; i < this.callbacks.length; i++) {
				if (this.callbacks[i] instanceof PasswordCallback) {
					((PasswordCallback) this.callbacks[i]).clearPassword();
				}
				this.callbacks[i]= null;
			}
			this.callbacks= null;
		}
	}
	
}
