/*=============================================================================#
 # Copyright (c) 2009, 2019 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.internal.rj.servi;

import java.io.File;
import java.rmi.RemoteException;

import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.rmi.RMIAddress;

import org.eclipse.statet.internal.rj.servi.server.RServiBackend;
import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.servi.node.RServiNode;


public abstract class NodeHandler {
	
	
	protected RServiNode node;
	
	RMIAddress address;
	File dir;
	Process process;
	
	private @Nullable String clientLabel;
	private @Nullable RServiBackend clientHandler;
	
	boolean isConsoleEnabled;
	
	private final long startTime;
	private long shutdownTime;
	
	
	public NodeHandler() {
		this.startTime= System.currentTimeMillis();
		this.shutdownTime= -1;
	}
	
	
	public boolean isConsoleEnabled() {
		return this.isConsoleEnabled;
	}
	
	public void enableConsole(final String authConfig) throws RjException {
		try {
			this.isConsoleEnabled= this.node.setConsole(authConfig);
		}
		catch (final Exception e) {
			Utils.logError("An error occurred when configuring the debug console.", e);
			throw new RjException("An error occurred when configuring the debug console. See server log for detail.");
		}
	}
	
	public void disableConsole() throws RjException {
		enableConsole(null);
	}
	
	public @Nullable RMIAddress getAddress() {
		return this.address;
	}
	
	
	void init(final RServiNode node, final Process process) {
		this.node= node;
		this.process= process;
	}
	
	void bindClient(final String name, final String host) throws RemoteException {
		final StringBuilder sb= new StringBuilder(80);
		if (name != null) {
			sb.append(name);
		}
		sb.append('@');
		sb.append(host);
		final String client= sb.toString();
		this.clientHandler= this.node.bindClient(client);
		setClientLabel(client);
	}
	
	void unbindClient() throws RemoteException {
		this.clientHandler= null;
		setClientLabel(null);
		this.node.unbindClient();
	}
	
	void shutdown() throws RemoteException {
		this.shutdownTime= System.currentTimeMillis();
		this.clientHandler= null;
		setClientLabel(null);
		final RServiNode node= this.node;
		this.node= null;
		if (node != null) {
			node.shutdown();
		}
	}
	
	@Nullable RServiBackend getClientHandler() {
		return this.clientHandler;
	}
	
	void setClientLabel(final @Nullable String clientLabel) {
		this.clientLabel= clientLabel;
	}
	
	public @Nullable String getClientLabel() {
		return this.clientLabel;
	}
	
	public long getStartTime() {
		return this.startTime;
	}
	
	public long getShutdownTime() {
		return this.shutdownTime;
	}
	
}
