/**
 * Maestro4BPEL - SOA Tools Platform.
 * Copyright (c) 2008 EBM Websourcing, http://www.ebmwebsourcing.com/
 *
 * This 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 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 library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * -------------------------------------------------------------------------
 * $id.java
 * -------------------------------------------------------------------------
 */
package com.ebmwebsourcing.easybpel.usecase.emptymessage;



import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.xml.namespace.QName;

import org.jdom.Element;
import org.jdom.JDOMException;
import org.junit.Test;

import com.ebmwebsourcing.easybpel.model.bpel.api.BPELException;
import com.ebmwebsourcing.easybpel.model.bpel.api.message.BPELExternalMessage;
import com.ebmwebsourcing.easybpel.model.bpel.impl.BPELFactoryImpl;
import com.ebmwebsourcing.easybpel.model.bpel.impl.message.BPELExternalMessageImpl;
import com.ebmwebsourcing.easybpel.model.bpel.impl.message.DefaultBPELMessageConverter;
import com.ebmwebsourcing.easyviper.core.api.Core;
import com.ebmwebsourcing.easyviper.core.api.CoreException;
import com.ebmwebsourcing.easyviper.core.impl.model.registry.ProcessContextDefinitionImpl;
import com.ebmwebsourcing.easyviper.environment.test.env.ExecutionEnvironmentTestFactory;
import com.ebmwebsourcing.easyviper.environment.test.env.TestSenderImpl;
import com.ebmwebsourcing.easyviper.environment.test.env.api.ClientEndpoint;
import com.ebmwebsourcing.easyviper.environment.test.env.api.ExecutionEnvironmentTest;
import com.ebmwebsourcing.easyviper.environment.test.env.api.ProviderEndpoint;
import com.ebmwebsourcing.easyviper.environment.test.util.MockServiceBuilder;
import com.ebmwebsourcing.easyviper.tools.MemoryReceiverImpl;

/**
 * @author Nicolas Salatge - eBM WebSourcing
 * 
 * @author Julien Lesbegueries - eBM WebSourcing
 * 
 * This use case tests BPEL engine for processes that invoke a partner that has an empty message as input.
 * 
 */
public class TestEmptyMessageProcess {

	/*
	 * Test of the invocation of the Axis GetVersion Web Service with a message containing a part, corresponding to an empty complex type
	 */
    @Test
	public void testGetVersionWithEmptyPart() throws CoreException, URISyntaxException, BPELException, InterruptedException, JDOMException, IOException  {
		final boolean explorer = false;

		java.util.logging.Logger log = java.util.logging.Logger.getLogger("test");
		log.setLevel(java.util.logging.Level.WARNING);
		// create execution environment
		ExecutionEnvironmentTest env = ExecutionEnvironmentTestFactory.newInstance().newEnvironment("TestEnvironnement", explorer);
		env.setLog(log);

		//// create core
		final Core core = BPELFactoryImpl.getInstance().newBPELEngine(DefaultBPELMessageConverter.get(), 1, MemoryReceiverImpl.class, 1, TestSenderImpl.class);
		core.setLog(log);
		env.setCore(core);

		//// create client
		ClientEndpoint client = env.createClientEndpoint("client");


		//// create providers
		ProviderEndpoint theProvider = env.createProviderEndpoint("VersionHttpSoap11Endpoint", VersionEmptyService.class);





		// store the definition
		core.getModel().getRegistry().storeProcessDefinition(new URI("./src/test/resources/processEmptyPart.bpel"),
				new ProcessContextDefinitionImpl(1));


		while(core.getEngine().getProcessInstanceRegistry().getProcessInstances().size() == 0) {
			log.finest("Wait the creation of process instances... "+ core.getEngine().getProcessInstanceRegistry().getProcessInstances().size());
			Thread.sleep(5000);
		}


		File xmlFile = new File("./src/test/resources/messages/processRequestEmptyPart.xml");

		BPELExternalMessage clientMessage = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://easybpel.version", "process"),
				"processSOAP",
				xmlFile,
				new QName("http://easybpel.version", "processRequest"),
				BPELExternalMessageImpl.class);


		client.send(clientMessage);
		
		
	
		System.out.println("Number of process instances : "+core.getEngine().getProcessInstanceRegistry().getProcessInstances().size());
		System.out.println("Number of process definitions : "+core.getModel().getRegistry().getAllProcessDefinitions().size());
		Thread.sleep(1000);

	

		if (explorer) {
			Thread.sleep(10000000);
		}

		int cpt=10;
		while(client.getResponse()==null && cpt>0){
			System.out.println("Wait for the client response.");
			Thread.sleep(1000);
			cpt--;
		}

		if(explorer) {
			Thread.sleep(10000000);
		}

		// ASSERTION client1
		BPELExternalMessage expectedResponse = new BPELExternalMessageImpl();
		Element content = MockServiceBuilder.buildContent(new File(
		"./src/test/resources/messages/processResponseEmptyPart.xml"));
		expectedResponse.setContent(content);


		assertEquals(expectedResponse.toString(), client.getResponse().toString());
		
	}

	
	/*
	 * Test of the invocation of the original Axis GetVersion Web Service with an empty message
	 */
	@Test
	public void testGetVersion() throws CoreException, URISyntaxException, BPELException, InterruptedException, JDOMException, IOException  {
		final boolean explorer = false;

		java.util.logging.Logger log = java.util.logging.Logger.getLogger("test");
		log.setLevel(java.util.logging.Level.WARNING);
		// create execution environment
		ExecutionEnvironmentTest env = ExecutionEnvironmentTestFactory.newInstance().newEnvironment("TestEnvironnement", explorer);
		env.setLog(log);

		//// create core
		final Core core = BPELFactoryImpl.getInstance().newBPELEngine(DefaultBPELMessageConverter.get(), 1, MemoryReceiverImpl.class, 1, TestSenderImpl.class);
		core.setLog(log);
		env.setCore(core);

		//// create client
		ClientEndpoint client = env.createClientEndpoint("client");


		//// create providers
		ProviderEndpoint theProvider = env.createProviderEndpoint("VersionHttpSoap11Endpoint", VersionService.class);





		// store the definition
		core.getModel().getRegistry().storeProcessDefinition(new URI("./src/test/resources/process.bpel"),
				new ProcessContextDefinitionImpl(1));


		while(core.getEngine().getProcessInstanceRegistry().getProcessInstances().size() == 0) {
			log.finest("Wait the creation of process instances... "+ core.getEngine().getProcessInstanceRegistry().getProcessInstances().size());
			Thread.sleep(5000);
		}


		File xmlFile = new File("./src/test/resources/messages/processRequest.xml");

		BPELExternalMessage clientMessage = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://easybpel.version", "process"),
				"processSOAP",
				xmlFile,
				new QName("http://easybpel.version", "processRequest"),
				BPELExternalMessageImpl.class);


		client.send(clientMessage);
		
		
	
		System.out.println("Number of process instances : "+core.getEngine().getProcessInstanceRegistry().getProcessInstances().size());
		System.out.println("Number of process definitions : "+core.getModel().getRegistry().getAllProcessDefinitions().size());
		Thread.sleep(1000);

	

		if (explorer) {
			Thread.sleep(10000000);
		}

		int cpt=10;
		while(client.getResponse()==null && cpt>0){
			System.out.println("Wait for the client response.");
			Thread.sleep(1000);
			cpt--;
		}

		if(explorer) {
			Thread.sleep(10000000);
		}

		// ASSERTION client1
		BPELExternalMessage expectedResponse = new BPELExternalMessageImpl();
		Element content = MockServiceBuilder.buildContent(new File(
		"./src/test/resources/messages/processResponse.xml"));
		expectedResponse.setContent(content);


		assertEquals(expectedResponse.toString(), client.getResponse().toString());
		
	}

}

