/**
 * Core4BPEL - 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.ident;


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.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.api.soa.message.ExternalMessage;
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
 */
public class TestIdentProcess {

    @Test
    public void testIdent() throws CoreException, URISyntaxException, BPELException, InterruptedException, JDOMException, IOException  {
		final boolean explorer = false;

		// create execution environment
		ExecutionEnvironmentTest env = ExecutionEnvironmentTestFactory.newInstance().newEnvironment("TestEnvironnement", explorer);

		//// create core
		final Core core = BPELFactoryImpl.getInstance().newBPELEngine(DefaultBPELMessageConverter.get(), 1, 
				MemoryReceiverImpl.class, 1, TestSenderImpl.class);
		env.setCore(core);

		//// create client
		ClientEndpoint client1 = env.createClientEndpoint("client1");
		ClientEndpoint client2 = env.createClientEndpoint("client2");
		ClientEndpoint client3 = env.createClientEndpoint("client3");
		ClientEndpoint client4 = env.createClientEndpoint("client4");



		//// create providers
		ProviderEndpoint gererIdentProvider = env.createProviderEndpoint("GererIdentClientSessionEJBEndpoint", GererIdentClientService.class);
		ProviderEndpoint awsidentcramProxyHeaderProvider = env.createProviderEndpoint("AWSNIDENTCRAM-ProxyHeaderEndpoint", AWSNIDENTCRAMProxyHeaderService.class);

		final int nbInstances = 1;
		
		// store the definition
		core.getModel().getRegistry().storeProcessDefinition(new URI("./src/test/resources/identAll/process.bpel"),
				new ProcessContextDefinitionImpl(nbInstances));

		while(core.getEngine().getProcessInstanceRegistry().getProcessInstances().size() < nbInstances){
			System.out.println("Wait for some process instances to be stored");
			Thread.sleep(2000);
		}

		// send client message
		File xmlFile = new File(
		"./src/test/resources/clientRequest/identByCriteresRequestMessage1.xml");
		BPELExternalMessage message1 = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://com.grc/", "identService"),
				"identServiceEndpoint", xmlFile,
				new QName("http://com.grc/", "identByCriteresRequestMessage"),
				BPELExternalMessageImpl.class);

		ExternalMessage response1 = client1.sendSync(message1);

		// ASSERTION
		BPELExternalMessage expectedResponse1 = new BPELExternalMessageImpl();
		expectedResponse1.setMessage("" +
				"<cns0:processByCriteresResponse xmlns:cns0=\"http://com.grc/\">" +
				"  <outputParam />" +
				"</cns0:processByCriteresResponse>" 
		);


		assertEquals(expectedResponse1.toString(), response1.toString());
		Thread.sleep(200);

		// Message 2
		xmlFile = new File(
		"./src/test/resources/clientRequest/identByCriteresRequestMessage2.xml");
		BPELExternalMessage message2 = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://com.grc/", "identService"),
				"identServiceEndpoint", xmlFile,
				new QName("http://com.grc/", "identByCriteresRequestMessage"), BPELExternalMessageImpl.class);

		ExternalMessage response2 = client2.sendSync(message2);

		xmlFile = new File(
		"./src/test/resources/clientRequest/identByCriteresResponseMessage2.xml");
		BPELExternalMessage expectedResponse2 = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://com.grc/", "identService"),
				"identServiceEndpoint", xmlFile,
				new QName("http://com.grc/", "identByCriteresResponseMessage"),
				BPELExternalMessageImpl.class);

		assertEquals(expectedResponse2.toString(), response2.toString());
		Thread.sleep(200);


		// TEST NIR

		// send client message
		xmlFile = new File(
		"./src/test/resources/clientRequest/identByNirRequestMessage1.xml");
		BPELExternalMessage message3 = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://com.grc/", "identService"),
				"identServiceEndpoint", xmlFile,
				new QName("http://com.grc/", "identByNirRequestMessage"), BPELExternalMessageImpl.class);

		ExternalMessage response3 = client3.sendSync(message3);

		// ASSERTION
		xmlFile = new File(
		"./src/test/resources/clientRequest/identByNirResponseMessage1.xml");
		BPELExternalMessage expectedResponse3 = (BPELExternalMessage) MockServiceBuilder.buildMessage(
				new QName("http://com.grc/", "identService"),
				"identServiceEndpoint", xmlFile,
				new QName("http://com.grc/","identByNirResponseMessage"), BPELExternalMessageImpl.class);

		assertEquals(expectedResponse3.toString(), response3.toString());
		Thread.sleep(200);

		// TEST 2

		BPELExternalMessage message4 = new BPELExternalMessageImpl();
		message4.setService(new QName("http://com.grc/", "identService"));
		message4.setEndpoint("identServiceEndpoint");
		message4.setQName(new QName("http://com.grc/", "identByNirRequestMessage"));
		message4.setMessage("" +
				"<com:process xmlns:com=\"http://com.grc/\">" +
				"         <nir>" +
				"            <com:nir>346</com:nir>" +
				"            <com:idDemandeur>347</com:idDemandeur>" +
				"            <com:organisme>348</com:organisme>" +
				"         </nir>" +
				"</com:process>" 
		);
		ExternalMessage response4 = client4.sendSync(message4);


		BPELExternalMessage expectedResponse4 = new BPELExternalMessageImpl();
		expectedResponse4.setMessage("" +
				"<tns:processByNirResponse xmlns:tns=\"http://com.grc/\">" +
				"  <tabassure xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"tns:identByNirResponse\">" +
				"    <tns:result xmlns:Q1=\"http://user.identclient.service.grc.com\" xsi:type=\"Q1:ArrayOfAssureDTO\" />" +
				"  </tabassure>" +
				"</tns:processByNirResponse>" 
		);


		assertEquals(expectedResponse4.toString(), response4.toString());
		Thread.sleep(200);

		// unstore the definition
		core.getModel().getRegistry().unStoreProcessDefinition(new URI("./src/test/resources/identAll/process.bpel"), true);


		if(explorer) {
			Thread.sleep(10000000);


		}
	}


}

