/*=============================================================================#
 # Copyright (c) 2009, 2017 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.srvext.auth;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;

import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.server.FxCallback;
import org.eclipse.statet.rj.server.srvext.ServerAuthMethod;
import org.eclipse.statet.rj.server.util.ServerUtils;


/**
 * Authentication method 'none'
 * without any authentication mechanism.
 */
public class FxAuthMethod extends ServerAuthMethod {
	
	
	private File file;
	private FileInputStream fileInputStream;
	
	private final byte[] pendingKey= new byte[1024];
	private FileChannel fileChannel;
	
	
	public FxAuthMethod() {
		super("fx", false);
	}
	
	
	@Override
	public void doInit(final String arg) throws RjException {
		final String configType;
		final String configValue;
		{	final String[] args= ServerUtils.getArgConfigValue(arg);
			configType= args[0];
			configValue= args[1];
		}
		if (configType.equals("file")) {
			if (configValue == null || configValue.length() == 0) {
				throw new RjException("Missing lock file name.", null);
			}
			this.file= new File(configValue);
			
			try {
				if (!this.file.exists()) {
					this.file.createNewFile();
				}
				this.fileChannel= new RandomAccessFile(this.file, "rws").getChannel();
				this.fileChannel.truncate(512);
			}
			catch (final IOException e) {
				throw new RjException("Cannot read lock file.", e);
			}
		}
		else {
			throw new RjException("Unsupported configuration type '"+configType+"'.", null);
		}
	}
	
	@Override
	protected Callback[] doCreateLogin() throws RjException {
		getRandom().nextBytes(this.pendingKey);
		try {
			this.fileChannel.position(this.fileChannel.size());
		}
		catch (final IOException e) {
			throw new RjException("Cannot read lock file.", e);
		}
		
		return new Callback[] {
				new NameCallback("Username"),
				new FxCallback(this.file.getPath(), this.pendingKey),
		};
	}
	
	@Override
	protected String doPerformLogin(final Callback[] callbacks) throws LoginException, RjException {
		final String userName= ((NameCallback) callbacks[0]).getName();
		final byte[] clientKey= ((FxCallback) callbacks[1]).getContent();
		if (clientKey.length < 1024) {
			throw new RjException("Unsufficient client key");
		}
		try {
			if (compare(this.pendingKey) && compare(clientKey)) {
				return userName;
			}
		}
		catch (final IOException e) {
			throw new RjException("Cannot read lock file.", e);
		}
		throw new FailedLoginException();
	}
	
	private boolean compare(final byte[] key) throws IOException {
		final byte[] check= new byte[key.length];
		final int n= this.fileChannel.read(ByteBuffer.wrap(check));
		if (n != key.length) {
			return false;
		}
		return Arrays.equals(key, check);
	}
	
}
