/**
 * 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.se.validation;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

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;
import org.ow2.petals.se.validation.model.ValidationConfiguration;
import org.ow2.petals.se.validation.model.ValidationConfigurationHandler;

import com.ebmwebsourcing.easycommons.lang.StringHelper;

/**
 * @author Roland Naudin - EBM WebSourcing
 * @author Vincent Zurczak - EBM WebSourcing
 */
public class ValidationSuManager extends AbstractServiceUnitManager {

	/**
	 * The 'schema' parameter of the SU configuration.
	 */
	private static final String XSD_PATH = "schema";

	/**
	 * A map associating service-unit names and Validation configuration.
	 */
	private final Map<String,ValidationConfigurationHandler> suNameToValidationConfigurationHandler =
		new ConcurrentHashMap<String,ValidationConfigurationHandler> ();



	/**
	 * Constructor.
	 * @param component the component's instance
	 */
	public ValidationSuManager( AbstractComponent component ) {
		super( component );
	}


	/*
	 * (non-Javadoc)
	 * @see org.ow2.petals.component.framework.su.AbstractServiceUnitManager
	 * #doDeploy(java.lang.String, java.lang.String, org.ow2.petals.component.framework.jbidescriptor.generated.Jbi)
	 */
	@Override
	protected void doDeploy(String serviceUnitName, String suRootPath, Jbi jbiDescriptor )
	throws PEtALSCDKException {

		// Control that there is only one Provides section in the SU
		if( jbiDescriptor.getServices().getConsumes() != null
				&& jbiDescriptor.getServices().getConsumes().size() != 0 )
			throw new PEtALSCDKException( "'Consumes' sections are not supported by this component." );

		final List<Provides> providesList = jbiDescriptor.getServices().getProvides();
		if( providesList == null || providesList.size() != 1 )
			throw new PEtALSCDKException( "Only one 'Provides' section is allowed by this component." );


		// Control that there is the required parameter
		Provides provides = providesList.get( 0 );
		ServiceUnitDataHandler suDatahandler = getSUDataHandlerForService( provides );
		ConfigurationExtensions extensions = suDatahandler.getConfigurationExtensions( provides );
		String schemaFileName = extensions.get( XSD_PATH );
		if( StringHelper.isNullOrEmpty( schemaFileName ))
			throw new PEtALSCDKException( "A configuration for this component must define the  '" + XSD_PATH + "' parameter.");


		// Create a configuration element
		ValidationConfiguration config = new ValidationConfiguration(
				schemaFileName.trim(),
				suRootPath,
				provides.getEndpointName(),
				serviceUnitName );


		// Create a handler and register these elements
		ValidationConfigurationHandler handler = new ValidationConfigurationHandler( config, this.logger );

		this.suNameToValidationConfigurationHandler.put( serviceUnitName, handler );
		((ValidationSe) this.component).registerValidationConfigurationHandler( provides.getEndpointName(), handler );
	}


	/*
	 * (non-Javadoc)
	 * @see org.ow2.petals.component.framework.su.AbstractServiceUnitManager
	 * #doStart(java.lang.String)
	 */
	@Override
	protected void doStart( String serviceUnitName ) throws PEtALSCDKException {

		ValidationConfigurationHandler handler = this.suNameToValidationConfigurationHandler.get( serviceUnitName );
		if( handler != null )
			handler.start( this.logger );
		else
			throw new PEtALSCDKException( "No configuration handler was found for the service-unit " + serviceUnitName + " (start)." );
	}


	/*
	 * (non-Javadoc)
	 * @see org.ow2.petals.component.framework.su.AbstractServiceUnitManager
	 * #doStop(java.lang.String)
	 */
	@Override
	protected void doStop( String serviceUnitName ) throws PEtALSCDKException {

		ValidationConfigurationHandler handler = this.suNameToValidationConfigurationHandler.get( serviceUnitName );
		if( handler != null )
			handler.stop();
		else
			throw new PEtALSCDKException( "No configuration handler was found for the service-unit " + serviceUnitName + " (stop)." );
	}


	/*
	 * (non-Javadoc)
	 * @see org.ow2.petals.component.framework.su.AbstractServiceUnitManager
	 * #doUndeploy(java.lang.String)
	 */
	@Override
	protected void doUndeploy( String serviceUnitName ) throws PEtALSCDKException {
		ValidationConfigurationHandler handler = this.suNameToValidationConfigurationHandler.remove( serviceUnitName );
		((ValidationSe) this.component).removeValidationConfigurationHandler( handler.getEndpointName());
	}
}
