/**
 * Copyright (c) 2009-2012 EBM WebSourcing, 2012-2013 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see <http://www.gnu.org/licenses/>
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.bc.sftp;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.ow2.petals.bc.sftp.connection.SFTPConnectionInfo;
import org.ow2.petals.bc.sftp.connection.SFTPConnectionInfoBuilder;
import org.ow2.petals.bc.sftp.connection.WrappedSftpClientFactory;
import org.ow2.petals.component.framework.AbstractComponent;
import org.ow2.petals.component.framework.api.configuration.ConfigurationExtensions;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.jbidescriptor.generated.Jbi;
import org.ow2.petals.component.framework.jbidescriptor.generated.Provides;
import org.ow2.petals.component.framework.su.AbstractServiceUnitManager;
import org.ow2.petals.component.framework.su.ServiceUnitDataHandler;

/**
 * @author Mathieu CARROLLE - EBM WebSourcing
 */
public class SFtpSuManager extends AbstractServiceUnitManager {

    private final Logger logger;

    public SFtpSuManager(AbstractComponent component, final Logger logger) {
        super(component);
        this.logger = logger;
    }

    @Override
    protected void doDeploy(String serviceUnitName, String suRootPath, Jbi jbiDescriptor)
            throws PEtALSCDKException {
        final ServiceUnitDataHandler handler = this.getServiceUnitDataHandlers().get(
                serviceUnitName);
        final Provides provides = handler.getDescriptor().getServices().getProvides().get(0);
        final ConfigurationExtensions extensions = handler.getConfigurationExtensions(provides);
        SFTPConnectionInfo connectionConfiguration;
        try {
            connectionConfiguration = SFTPConnectionInfoBuilder.buildSFTPConnectionInfo(extensions,
                    provides.getRetrypolicy());
        } catch (ConfigurationException e) {
            throw new PEtALSCDKException(e);
        }
        final WrappedSftpClientFactory factory = new WrappedSftpClientFactory(
                connectionConfiguration, this.logger);
        final GenericObjectPool pool = new GenericObjectPool(factory);
        pool.setConfig(this.configurePool(connectionConfiguration, pool));
        ((SFTPComponent) this.component).getMapOfPool().put(provides, pool);
    }

    @Override
    protected void doUndeploy(String serviceUnitName) throws PEtALSCDKException {
        final ServiceUnitDataHandler handler = this.getServiceUnitDataHandlers().get(
                serviceUnitName);
        final Provides provides = handler.getDescriptor().getServices().getProvides().get(0);
        final ObjectPool pool = ((SFTPComponent) this.component).getMapOfPool().get(provides);
        try {
            if (pool != null) {
                this.logger.finest("Closing pool's resource");
                pool.clear();
                pool.close();
            }
        } catch (Exception e) {
            this.logger.finest("Exception when closing pool's resource: " + e.getMessage());
        }
    }

    /**
     * Configure the pool
     * 
     * @param connectionConfiguration
     * @param pool
     * @return
     */
    private final Config configurePool(final SFTPConnectionInfo connectionConfiguration,
            final GenericObjectPool pool) {
        Config conf = new Config();
        int maxConnection = connectionConfiguration.getMaxConnection();
        if (maxConnection <= 0) {
            conf.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
        } else {
            // On borrow action, we block until an object is free
            conf.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
            // Wait is unlimited;
            conf.maxWait = -1;
            conf.maxActive = maxConnection;
            conf.maxIdle = maxConnection;
        }
        if (this.logger.isLoggable(Level.FINEST))
            this.logger.finest("Number of maximum connection for the pool: " + maxConnection);
        conf.testOnBorrow = true;
        conf.testOnReturn = true;
        return conf;
    }

}
