/**
 * 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.notification;

import static org.junit.Assert.*;

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.engine.Execution;
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.tools.MemoryReceiverImpl;

/**
 * @author Nicolas Salatge - eBM WebSourcing
 */
public class TestNotificationProcess {

    @Test
	public void testNotification() throws CoreException, URISyntaxException,
			BPELException, InterruptedException, JDOMException, IOException {
		final boolean explorer = false;

		// create execution environment
		ExecutionEnvironmentTest env = ExecutionEnvironmentTestFactory
				.newInstance().newEnvironment("TestEnvironnement", explorer);

		// // create maestro
		final Core core = BPELFactoryImpl.getInstance().newBPELEngine(
				DefaultBPELMessageConverter.get(), 1, MemoryReceiverImpl.class,
				1, TestSenderImpl.class);
		env.setCore(core);

		// // create client
		ClientEndpoint client = env.createClientEndpoint("client");
		ClientEndpoint notifiyClient = env.createClientEndpoint("notifyClient");

		// // create providers
		ProviderEndpoint weatherProvider = env.createProviderEndpoint(
				"WeatherManagementServiceEndpoint",
				ProducerNotificationService.class);

		// store the definition
		core.getModel().getRegistry().storeProcessDefinition(
				new URI("./src/test/resources/process.bpel"),
				new ProcessContextDefinitionImpl());
		// send client message
		BPELExternalMessage message = new BPELExternalMessageImpl();
		message.setService(new QName(
				"http://petals.ow2.org/weatherNotification",
				"WeatherNotificationService"));
		message.setEndpoint("weatherNotificationServiceEndpoint");
		message.setQName(new QName("http://petals.ow2.org/weatherNotification",
				"weatherNotificationRequestMessage"));
		message
				.setMessage(""
						+ "<weat:weatherNotificationRequest xmlns:weat=\"http://petals.ow2.org/weatherNotification\">"
						+ "         <in>?</in>"
						+ "</weat:weatherNotificationRequest>");

		client.send(message);

		com.ebmwebsourcing.easyviper.core.api.engine.Process process = null;
		while (core.getEngine().getProcessInstanceRegistry()
				.getProcessInstances().size() == 0) {
			System.out.println("Wait the creation of process");
		}
		process = core.getEngine().getProcessInstanceRegistry()
				.getProcessInstances().get(0);

		while (process.getParentExecution() == null) {
			System.out.println("Wait that the process start");
		}

		for (int i = 0; i < 3; i++) {
			System.out
					.println("*************************----******************************");
			while (process.getParentExecution().getState() != Execution.State.SUSPENDED) {
				System.out
						.println("Wait that the process arrive on the next receive " + process.getParentExecution().getState());
				Thread.sleep(1000);
			}
			System.out.println("################################----******************************");

			BPELExternalMessage notifyMessage = new BPELExternalMessageImpl();
			notifyMessage.setService(new QName(
					"http://petals.ow2.org/weatherNotification",
					"WeatherNotificationService"));
			notifyMessage.setEndpoint("weatherNotificationServiceEndpoint");
			notifyMessage.setQName(new QName(
					"http://petals.ow2.org/weatherNotification",
					"NotifyMessage"));
			notifyMessage
					.setMessage(""
							+ "<b:Notify xmlns:b=\"http://docs.oasis-open.org/wsn/b-2\" xmlns:add=\"http://www.w3.org/2005/08/addressing\">"
							+ "<b:NotificationMessage>"
							+ "<b:SubscriptionReference>"
							+ "<add:Address>?</add:Address>"
							+ "<add:ReferenceParameters></add:ReferenceParameters>"
							+ "<add:Metadata></add:Metadata>"
							+ "</b:SubscriptionReference>"
							+ "<b:Topic Dialect=\"?\">egero</b:Topic>"
							+ "<b:ProducerReference>"
							+ "<add:Address>?</add:Address>"
							+ "<add:ReferenceParameters> </add:ReferenceParameters>"
							+ "<add:Metadata></add:Metadata>"
							+ "</b:ProducerReference>"
							+ "<b:Message></b:Message>"
							+ "</b:NotificationMessage>" + "</b:Notify>");
			notifiyClient.send(notifyMessage);
		}

		while (process.getParentExecution().getState() != Execution.State.ENDED) {
			System.out.println("Wait that the end of the process");
		}

		// ASSERTION
		BPELExternalMessage expectedResponse = new BPELExternalMessageImpl();
		expectedResponse
				.setMessage(""
						+ "<tns:weatherNotificationResponse xmlns:tns=\"http://petals.ow2.org/weatherNotification\">"
						+ "<out xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"xsd:string\">Suscribe with success</out>"
						+ "</tns:weatherNotificationResponse>");

		if (explorer) {
			Thread.sleep(10000000);
		}
		ExternalMessage response = client.getResponse();
		System.out
				.println("##################:::::::::::::::::::::::: RESPONSE ::::::::::::::::::::");
		String responseStr = response.toString();
		System.out.println(responseStr);
		System.out
				.println("##################:::::::::::::::::::::::: CHECK RESPONSE");
		assertEquals(expectedResponse.toString(), responseStr);
	}

}