/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#include "openmrcp_client.h"
#include "mrcp_resource_manager.h"

#define DEFAULT_MRCP_CLIENT_VERSION MRCP_VERSION_2

mrcp_signaling_agent_t* mrcp_client_sofia_agent_create(const char *client_ip, unsigned short client_port, 
													   const char *server_ip, unsigned short server_port, 
													   const char *resource_location, apr_pool_t *pool);
mrcp_proto_agent_t* mrcp_client_v2_agent_create();

mrcp_signaling_agent_t* mrcp_client_rtsp_agent_create(const char *client_ip, unsigned short client_port, 
													  const char *server_ip, unsigned short server_port, 
													  const char *resource_location, apr_pool_t *pool);
mrcp_proto_agent_t* mrcp_client_rtsp_proto_agent_create(mrcp_signaling_agent_t *signaling_agent);

mrcp_media_agent_t* mrcp_live_media_agent_create(const char *ip, unsigned short rtp_port_min, unsigned short rtp_port_max, apr_pool_t *pool);


static mrcp_signaling_agent_t* module_signaling_agent_create(mrcp_client_module_loader_t *module_loader, apr_pool_t *pool)
{
	openmrcp_client_options_t *options = (openmrcp_client_options_t *)module_loader;
	mrcp_signaling_agent_t *signaling_agent = NULL;
	switch(options->proto_version) {
		case MRCP_VERSION_1:
			signaling_agent = mrcp_client_rtsp_agent_create(
									options->client_ip,options->client_port,
									options->server_ip,options->server_port,
									options->resource_location,pool);
			break;
		case MRCP_VERSION_2:
			signaling_agent = mrcp_client_sofia_agent_create(
									options->client_ip,options->client_port,
									options->server_ip,options->server_port,
									options->resource_location,pool);
			break;
		default:
			break;
	}
	return signaling_agent;
}

static mrcp_proto_agent_t* module_proto_agent_create(mrcp_client_module_loader_t *module_loader, mrcp_signaling_agent_t *signaling_agent, apr_pool_t *pool)
{
	openmrcp_client_options_t *options = (openmrcp_client_options_t *)module_loader;
	mrcp_proto_agent_t *proto_agent = NULL;
	switch(options->proto_version) {
		case MRCP_VERSION_1:
			proto_agent = mrcp_client_rtsp_proto_agent_create(signaling_agent);
			break;
		case MRCP_VERSION_2:
			proto_agent = mrcp_client_v2_agent_create(pool);
			break;
		default:
			break;
	}
	return proto_agent;
}

static mrcp_media_agent_t* module_media_agent_create(mrcp_client_module_loader_t *module_loader, apr_pool_t *pool)
{
	openmrcp_client_options_t *options = (openmrcp_client_options_t *)module_loader;
	if(!options) {
		return NULL;
	}
	
	return mrcp_live_media_agent_create(options->client_ip,
		options->rtp_port_min,options->rtp_port_max,pool);
}

static mrcp_resource_container_t* module_resource_container_create(mrcp_client_module_loader_t *module_loader, apr_pool_t *pool)
{
	openmrcp_client_options_t *options = (openmrcp_client_options_t *)module_loader;
	if(!options) {
		return NULL;
	}

	return mrcp_client_resource_container_create(options->proto_version,options->resource_string_table,pool);
}

static mrcp_status_t openmrcp_client_options_validate(openmrcp_client_options_t *options)
{
	if(!options) {
		return MRCP_STATUS_FAILURE;
	}

	if(options->proto_version != MRCP_VERSION_1 && options->proto_version != MRCP_VERSION_2) {
		options->proto_version = DEFAULT_MRCP_CLIENT_VERSION;
	}

	if(options->client_ip == NULL) {
		options->client_ip = "127.0.0.1";
	}
	if(options->client_port == 0) {
		options->client_port = 8062;
	}
	if(options->server_ip == NULL) {
		options->server_ip = "127.0.0.1";
	}
	if(options->server_port == 0) {
		switch(options->proto_version) {
			case MRCP_VERSION_1:
				options->server_port = 1554; /*554*/
				break;
			case MRCP_VERSION_2:
				options->server_port = 8060; /*5060*/
				break;
			default:
				break;
		}
	}
	if(options->rtp_port_min == 0) {
		options->rtp_port_min = 4000;
	}
	if(options->rtp_port_max == 0) {
		options->rtp_port_max = 6000;
	}

	if(!options->resource_location) {
		switch(options->proto_version) {
			case MRCP_VERSION_1:
				options->resource_location = "media";
				break;
			case MRCP_VERSION_2:
				options->resource_location = "";
				break;
			default:
				break;
		}
	}
	
	options->module_loader.signaling_agent_create = module_signaling_agent_create;
	options->module_loader.proto_agent_create = module_proto_agent_create;
	options->module_loader.media_agent_create = module_media_agent_create;
	options->module_loader.resource_container_create = module_resource_container_create;
	return MRCP_STATUS_SUCCESS;
}

openmrcp_client_options_t* openmrcp_client_options_create(apr_pool_t *pool)
{
	openmrcp_client_options_t *options = apr_palloc(pool,sizeof(openmrcp_client_options_t));
	options->proto_version = DEFAULT_MRCP_CLIENT_VERSION;
	options->client_ip = NULL;
	options->client_port = 0;
	options->server_ip = NULL;
	options->server_port = 0;
	options->rtp_port_min = 0;
	options->rtp_port_max = 0;
	options->resource_location = NULL;
	options->resource_string_table = NULL;
	return options;
}

mrcp_client_t* openmrcp_client_start(openmrcp_client_options_t *options, mrcp_client_context_t *context)
{
	if(!options || !context) {
		return NULL;
	}

	openmrcp_client_options_validate(options);

	return mrcp_client_start(&options->module_loader,context);
}

mrcp_status_t openmrcp_client_shutdown(mrcp_client_t *mrcp_client)
{
	return mrcp_client_shutdown(mrcp_client);
}
