/*
 * Copyright  2004 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.utility;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.transport.http.SimpleHTTPServer;

public class KandulaListener {

	private static KandulaListener instance = null;

	private ConfigurationContext responseConfigurationContext;

	protected static AxisOperation[] operations;

	private SimpleHTTPServer receiver = null;

	private boolean serverStarted = false;

	public int serverPort;

	private KandulaListener() throws IOException {
		KandulaConfiguration configuration = KandulaConfiguration.getInstance();
		responseConfigurationContext = ConfigurationContextFactory
				.createConfigurationContextFromFileSystem(configuration
						.getKandulaListenerRepository(), configuration
						.getKandulaListenerAxis2Xml());
		try {
			serverPort = Integer.parseInt(KandulaConfiguration.getInstance()
					.getKadulaListenerPort());
		} catch (Exception e) {
			serverPort = 5059;
		}
		while (receiver == null) {

			receiver = new SimpleHTTPServer(responseConfigurationContext,
					serverPort);

		}
	}

	public static KandulaListener getInstance() throws IOException {
		if (instance == null) {
			instance = new KandulaListener();
		}
		return instance;
	}

	public void start() throws IOException {
		if (!serverStarted) {

			receiver.start();
			serverStarted = true;
			System.out.print("Server started on port " + serverPort + ".....");
		}

	}

	public void stop() {
		receiver.stop();
		serverStarted = false;
	}

	/**
	 * @param service
	 * @throws AxisFault
	 *             To add services with only one operation, which is the
	 *             frequent case in reponses
	 */
	public void addService(AxisService service) throws AxisFault {

		service.setClassLoader(Thread.currentThread().getContextClassLoader());
		HashMap allServices = responseConfigurationContext
				.getAxisConfiguration().getServices();

		if (allServices.get(service.getName()) == null) {

			responseConfigurationContext.getAxisConfiguration().addService(
					service);
			// TODO : check how to do this or this is neccessary anymore
			// Utils.resolvePhases(receiver.getSystemContext()
			// .getAxisConfiguration(), service);
		}

	}

	public String getHost() throws UnknownHostException {
		return "http://"
				+ InetAddress.getLocalHost().getHostAddress()
				+ ":"
				+ KandulaConfiguration.getInstance()
						.getKadulaListenerPortForEPR() + "/axis2/services/";
	}
}