/*
 * Copyright 2004,2005 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.kandula.integration;

/**
 * @author <a href="mailto:thilina@opensource.lk">Thilina Gunarathne </a>
 */

import java.io.File;

import junit.framework.TestCase;

import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.transport.http.SimpleHTTPServer;
import org.apache.kandula.initiator.TransactionManager;
import org.apache.kandula.integration.xsd.CreditOperation;
import org.apache.kandula.integration.xsd.DebitOperation;

public class CompletionCommitTest extends TestCase {

	private String repository = "target/testing-repository";

	private KandulaDemoServiceKandulaDemoServiceSOAP11Port_httpStub stub;

	private SimpleHTTPServer server;

	public CompletionCommitTest() throws Exception {
		this(CompletionCommitTest.class.getName());
	}

	public CompletionCommitTest(String testName) throws Exception {
		super(testName);
		ConfigurationContext configurationContext = ConfigurationContextFactory
		.createConfigurationContextFromFileSystem("target/initiator-repository", "target/initiator-repository"
				+ "/axis2.xml");

		stub = new KandulaDemoServiceKandulaDemoServiceSOAP11Port_httpStub(configurationContext, "http://localhost:8081/axis2/services/KandulaDemoService");
	}

	protected void setUp() throws Exception {
		File file = new File(repository);
		File configFile = new File(repository + "/axis2.xml");
		if (!file.exists()) {
			throw new Exception("repository directory " + file.getAbsolutePath()
					+ " does not exists");
		}
		ConfigurationContext er = ConfigurationContextFactory
				.createConfigurationContextFromFileSystem(file.getAbsolutePath(), configFile
						.getAbsolutePath());

		server = new SimpleHTTPServer(er, 8081);

		try {
			server.start();
			System.out.print("Server started on port " + 8081 + ".....");
		} finally {

		}
	}

	protected void tearDown() throws Exception {
		server.stop();
	}
	
//	public void testRegistration() throws Exception {
//		TransactionManager tm = new TransactionManager("target/initiator-repository",
//				"target/initiator-repository/axis2.xml");
//		tm.begin("http://localhost:8082/axis2/services/ActivationCoordinator");
//		tm.commit();
//		Thread.sleep(5000);
//	}

	public void testCompletionCommit() throws Exception {
		TransactionManager tm = new TransactionManager("target/initiator-repository",
				"target/initiator-repository/axis2.xml");
		tm.begin("http://localhost:8081/axis2/services/ActivationCoordinator");
		stub.creditOperation(new CreditOperation());
		stub.debitOperation(new DebitOperation());
		tm.commit();
		Thread.sleep(5000);
	}

	//	public void testEchoXMLSync() throws Exception {
	//		// TransactionManager tm = new TransactionManager(
	//		// Constants.WS_AT,
	//		// new EndpointReference(
	//		// "http://localhost:8081/axis2/services/ActivationCoordinator"));
	//		// tm.begin("target/initiator-repository",
	//		// "target/initiator-repository/axis2.xml", false);
	//		// try {
	//		// stub.creditOperation();
	//		// } catch (Exception e) {
	//		// tm.rollback();
	//		// }
	//		// tm.commit();
	//	}
}