/*=============================================================================#
 # 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 static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.rmi.RemoteException;
import java.util.NoSuchElementException;

import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.rmi.RMIRegistry;
import org.eclipse.statet.jcommons.runtime.CommonsRuntime;
import org.eclipse.statet.jcommons.status.ErrorStatus;

import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.RjInitFailedException;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.servi.RServiUtils;
import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
import org.eclipse.statet.rj.servi.node.RServiNodeManager;


@NonNullByDefault
public class LocalNodeManager implements RServiNodeManager, Disposable {
	
	
	private class ThisNodeHandler extends NodeHandler implements RServiImpl.PoolRef {
		
		@Override
		public void returnObject(final long accessId) throws RjException, RemoteException {
			returnRServi(accessId);
		}
		
	}
	
	
	private final String id;
	
	private final RMIRegistry registry;
	
	private final LocalNodeFactory factory;
	
	private @Nullable ThisNodeHandler handler;
	
	private boolean inUse;
	private long accessId;
	
	
	public LocalNodeManager(final String id, final RMIRegistry registry, final LocalNodeFactory factory) {
		if (id == null || registry == null || factory == null) {
			throw new NullPointerException();
		}
		this.id= id;
		this.registry= registry;
		this.factory= factory;
		
		Utils.preLoad();
	}
	
	
	@Override
	public String getId() {
		return this.id;
	}
	
	@Override
	public RServiNodeFactory getFactory() {
		return this.factory;
	}
	
	@Override
	public void dispose() {
		stop();
	}
	
	@Override
	public synchronized void start() throws RjException {
		if (this.handler != null) {
			return;
		}
		try {
			final ThisNodeHandler handler= new ThisNodeHandler();
			this.factory.createNode(handler);
			this.handler= handler;
			CommonsRuntime.getEnvironment().addStoppingListener(this);
		}
		catch (final Throwable e) {
			CommonsRuntime.log(new ErrorStatus(RServiUtils.RJ_SERVI_ID,
					Messages.StartNode_error_message, e ));
			throw new RjInitFailedException(Messages.StartLocal_pub_error_message,
					(e instanceof RjException) ? e : null);
		}
	}
	
	@Override
	public synchronized void stop() {
		if (this.handler == null) {
			return;
		}
		CommonsRuntime.getEnvironment().removeStoppingListener(this);
		if (this.inUse) {
			returnRServi(this.accessId);
			if (this.handler == null) {
				return;
			}
		}
		final ThisNodeHandler handler= nonNullAssert(this.handler);
		this.handler= null;
		this.factory.stopNode(handler);
	}
	
	@Override
	public synchronized RServi getRServi(final String name) throws NoSuchElementException, RjException {
		if (this.handler == null) {
			start();
		}
		if (this.inUse) {
			throw new NoSuchElementException(Messages.GetRServi_NoInstance_pub_Single_message);
		}
		try {
			final ThisNodeHandler handler= nonNullAssert(this.handler);
			handler.bindClient(name, "local");
			this.inUse= true;
			return new RServiImpl(this.accessId, handler, handler.getClientHandler());
		}
		catch (final Throwable e) {
			CommonsRuntime.log(new ErrorStatus(RServiUtils.RJ_SERVI_ID,
					Messages.BindClient_error_message, e ));
			throw new RjException(Messages.GetRServi_pub_error_message);
		}
	}
	
	private synchronized void returnRServi(final long accessId) {
		if (this.handler == null) {
			return;
		}
		if (this.accessId != accessId) {
			throw new IllegalStateException("Access id no longer valid.");
		}
		try {
			final ThisNodeHandler handler= nonNullAssert(this.handler);
			this.inUse= false;
			this.accessId++;
			handler.unbindClient();
		}
		catch (final Throwable e) {
			CommonsRuntime.log(new ErrorStatus(RServiUtils.RJ_SERVI_ID,
					Messages.UnbindClient_error_message, e ));
			stop();
		}
	}
	
}
