/*=============================================================================#
 # 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.rmi.Remote;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.Collection;
import java.util.NoSuchElementException;

import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
import org.eclipse.statet.jcommons.rmi.RMIRegistry;

import org.eclipse.statet.rj.RjException;
import org.eclipse.statet.rj.RjInitFailedException;
import org.eclipse.statet.rj.server.ServerLogin;
import org.eclipse.statet.rj.servi.RServi;
import org.eclipse.statet.rj.servi.node.RServiNodeFactory;
import org.eclipse.statet.rj.servi.node.RServiPool;
import org.eclipse.statet.rj.servi.pool.PoolConfig;
import org.eclipse.statet.rj.servi.pool.PoolNodeObject;
import org.eclipse.statet.rj.servi.pool.RServiPoolManager;


public class PoolManager implements RServiPool, RServiPoolManager {
	
	
	private final String id;
	
	private final RMIRegistry registry;
	
	private Remote thisRemote;
	
	private APool2 pool;
	private APool2NodeFactory poolFactory;
	private PoolConfig poolConfig;
	
	private NodeFactory nodeFactory;
	
	private final CopyOnWriteIdentityListSet<PoolListener> poolListeners= new CopyOnWriteIdentityListSet<>();
	private final Stats stats;
	
	
	public PoolManager(final String id, final RMIRegistry registry) {
		if (id == null || registry == null) {
			throw new NullPointerException();
		}
		this.id= id;
		this.registry= registry;
		this.stats= new Stats();
		this.poolListeners.add(this.stats);
		this.poolConfig= new PoolConfig();
		
		Utils.preLoad();
	}
	
	
	@Override
	public String getId() {
		return this.id;
	}
	
	@Override
	public NodeFactory getFactories() {
		return this.nodeFactory;
	}
	
	@Override
	public synchronized void addNodeFactory(final RServiNodeFactory factory) {
		this.nodeFactory= (NodeFactory) factory;
	}
	
	@Override
	public synchronized void setConfig(final PoolConfig config) {
		if (this.pool != null) {
			this.pool.setConfig(config);
			this.poolFactory.setMaxUsageCount(config.getMaxUsageCount());
		}
		this.poolConfig= config;
	}
	
	@Override
	public PoolConfig getConfig() {
		return this.poolConfig;
	}
	
	public void addPoolListener(final PoolListener listener) {
		this.poolListeners.add(listener);
	}
	
	public void removePoolListener(final PoolListener listener) {
		this.poolListeners.remove(listener);
	}
	
	@Override
	public synchronized void init() throws RjException {
		this.poolFactory= new APool2NodeFactory(this.nodeFactory, this.poolListeners);
		this.poolFactory.setMaxUsageCount(this.poolConfig.getMaxUsageCount());
		this.pool= new APool2(this.poolFactory, this.poolConfig);
		
		Utils.logInfo("Publishing pool in registry...");
		if (this.registry != null) {
			RMIClientSocketFactory clientSocketFactory= null;
			RMIServerSocketFactory serverSocketFactory= null;
			if (this.registry.getAddress().isSsl()) {
				clientSocketFactory= new SslRMIClientSocketFactory();
				serverSocketFactory= new SslRMIServerSocketFactory(null, null, true);
			}
			try {
				this.thisRemote= UnicastRemoteObject.exportObject(this, 0,
						clientSocketFactory, serverSocketFactory );
				this.registry.getRegistry().rebind(PoolConfig.getPoolName(this.id), this.thisRemote);
			}
			catch (final Exception e) {
				try {
					stop(8);
				}
				catch (final Exception ignore) {}
				Utils.logError("An error occurred when binding the pool in the registry.", e);
				throw new RjInitFailedException("An error occurred when publishing the pool in the registry.");
			}
		}
	}
	
	@Override
	public Collection<? extends PoolNodeObject> getPoolNodeObjects() {
		return this.poolFactory.getAllObjects();
	}
	
	public boolean isInitialized() {
		return (this.thisRemote != null);
	}
	
	@Override
	public synchronized void stop(final int mode) throws RjException {
		Utils.logInfo("Unpublishing pool...");
		if (this.registry != null) {
			try {
				this.registry.getRegistry().unbind(PoolConfig.getPoolName(this.id));
			}
			catch (final Exception e) {
				if (mode != 8) {
					Utils.logError("An error occurred when unbinding the pool from the registry.", e);
				}
			}
		}
		if (this.thisRemote != null) {
			try {
				this.thisRemote= null;
				UnicastRemoteObject.unexportObject(this, true);
			}
			catch (final Exception e) {
				if (mode != 8) {
					Utils.logError("An error occurred when unexport the pool.", e);
				}
			}
		}
		
		try {
			Thread.sleep(1000);
		}
		catch (final InterruptedException e) {
		}
		if (PoolManager.this.pool != null) {
			Utils.logInfo("Closing R nodes...");
			try {
				PoolManager.this.pool.close(this.poolConfig.getEvictionTimeout());
			}
			catch (final Exception e) {
				Utils.logError("An error occurred when closing the pool.", e);
			}
			finally {
				Runtime.getRuntime().gc();
			}
		}
	}
	
	@Override
	public RServi getRServi(final String name, final ServerLogin login) throws NoSuchElementException, RjException {
		final APool2NodeHandler handler= getPoolObject(name);
		return new RServiImpl(handler.getAccessId(), handler, handler.getClientHandler());
	}
	
	public APool2NodeHandler getPoolObject(final String client) throws NoSuchElementException, RjException {
		try {
			return this.pool.borrowObject(client);
		}
		catch (final NoSuchElementException e) {
			this.stats.logServRequestFailed(3);
			throw new NoSuchElementException(Messages.GetRServi_NoInstance_pub_Pool_message);
		}
		catch (final Exception e) {
			this.stats.logServRequestFailed(4);
			Utils.logError(Messages.BindClient_error_message, e);
			throw new RjException(Messages.GetRServi_pub_error_message);
		}
	}
	
	@Override
	public RServiPoolManager.Counter getCounter() {
		final RServiPoolManager.Counter counter= new RServiPoolManager.Counter();
		synchronized (this.pool) {
			counter.numIdling= this.pool.getNumIdle();
			counter.numInUse= this.pool.getNumActive();
			counter.numTotal= counter.numIdling + counter.numTotal;
			counter.maxIdling= -1;
			counter.maxInUse= this.poolFactory.getStatMaxAllocated();
			counter.maxTotal= this.poolFactory.getStatMaxTotal();
		}
		return counter;
	}
	
}
