/*
 * 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 <apr_getopt.h>
#include "openmrcp_server.h"

#ifdef CUSTOM_MRCP_RESOURCE_NAMES
/* custom string table of MRCP resources (mrcp_resource_set_t) */
static const apt_string_table_item_t custom_resource_string_table[] = {
	{"TTS",3,0},
	{"ASR",3,0}
};
#endif

static void usage()
{
	printf(
		"\n"
		"Usage:\n"
		"\n"
		"  openmrcpserver [options]\n"
		"\n"
		"  Available options:\n"
		"\n"
		"   -p [--proto] version string  : Set the MRCP vesrion (MRCPv1 or MRCPv2). Default is a MRCPv2\n"
		"\n"
		"   -i [--interface] ip:port     : Set the local IP address and SIP port. Default is a 127.0.0.1:8060\n"
		"\n"
		"   -m [--mrcp-port] port        : Set the server MRCP port. Default is a 1544\n"
		"\n"
		"   -b [--rtp-port-min] port     : Set the min RTP port. Default is a 6000\n"
		"\n"
		"   -e [--rtp-port-max] port     : Set the max RTP port. Default is a 8000\n"
		"\n"
		"   -s [--synth-plugin] path     : Set the synthesizer plugin. Default is a demosynth\n"
		"\n"
		"   -r [--recog-plugin] path     : Set the recognizer plugin. Default is a demorecog\n"
		"\n"
		"   -u [--res-location] location : Set the location of MRCP resources.\n"
		"\n"
		"   -l [--log] priority          : Set the log priority (0-emergency, ..., 7-debug). Default is a 6-info \n"
		"\n");
}

static openmrcp_server_options_t* load_options(int argc, const char * const *argv, apr_pool_t *pool)
{
	openmrcp_server_options_t *options;
	apr_status_t rv;
	apr_getopt_t *opt;
	int optch;
	const char *optarg;

	static const apr_getopt_option_t opt_option[] = {
		/* long-option, short-option, has-arg flag, description */
		{ "proto",        'p', TRUE,  "MRCP version" },      /* -p arg or --proto arg */
		{ "interface",    'i', TRUE,  "interface ip:port" }, /* -i arg or --interface arg */
		{ "mrcp-port",    'm', TRUE,  "MRCP port" },         /* -m arg or --mrcp-port arg */
		{ "rtp-port-min", 'b', TRUE,  "min RTP port" },      /* -b arg or --rtp-port-min arg */
		{ "rtp-port-max", 'e', TRUE,  "max RTP port" },      /* -e arg or --rtp-port-max arg */
		{ "synth-plugin", 's', TRUE,  "synthesizer plugin" },/* -s arg or --synth-plugin arg */
		{ "recog-plugin", 'r', TRUE,  "recognizer plugin" }, /* -s arg or --recog-plugin arg */
		{ "res-location", 'u', TRUE,  "resource location" }, /* -u arg or --res-location arg */
		{ "log",          'l', TRUE,  "log priority" },      /* -l arg or --log arg */
		{ "help",         'h', FALSE, "show help" },         /* -h or --help */
		{ NULL, 0, 0, NULL },                                /* end */
	};

	apt_log_priority_set(APT_PRIO_INFO);
	options = openmrcp_server_options_create(pool);
	if(!options) {
		return NULL;
	}
	
	rv = apr_getopt_init(&opt, pool , argc, argv);
	if(rv != APR_SUCCESS) {
		return NULL;
	}

	while((rv = apr_getopt_long(opt, opt_option, &optch, &optarg)) == APR_SUCCESS) {
		switch(optch) {
			case 'p':
			{
				if(optarg) {
					if(apt_str_compare(optarg,"MRCPv1") == TRUE) {
						options->proto_version = MRCP_VERSION_1;
					}
					else if(apt_str_compare(optarg,"MRCPv2") == TRUE) {
						options->proto_version = MRCP_VERSION_2;
					}
				}
				break;
			}
			case 'i':
			{
				char *scope = NULL;
				apr_parse_addr_port(&options->local_ip,&scope,&options->local_port,optarg,pool);
				break;
			}
			case 'm':
				if(optarg) {
					options->mrcp_port = (apr_port_t)atoi(optarg);
				}
				break;
			case 'b':
				if(optarg) {
					options->rtp_port_min = (apr_port_t)atoi(optarg);
				}
				break;
			case 'e':
				if(optarg) {
					options->rtp_port_max = (apr_port_t)atoi(optarg);
				}
				break;
			case 's':
				if(optarg) {
					if(apr_dso_load(&options->synth_plugin,optarg,pool) != APR_SUCCESS) {
						char derr[512] = "";
						apr_dso_error(options->synth_plugin,derr,sizeof(derr));
						printf("%s\n",derr);
					}
				}
				break;
			case 'r':
				if(optarg) {
					if(apr_dso_load(&options->recog_plugin,optarg,pool) != APR_SUCCESS) {
						char derr[512] = "";
						apr_dso_error(options->recog_plugin,derr,sizeof(derr));
						printf("%s\n",derr);
					}
				}
				break;
			case 'u':
				if(optarg) {
					options->resource_location = apr_pstrdup(pool,optarg);
				}
				break;
			case 'l':
				if(optarg) {
					apt_log_priority_set(atoi(optarg));
				}
				break;
			case 'h':
				usage();
				return NULL;
		}
	}

	if(rv != APR_EOF) {
		usage();
		return NULL;
	}

#ifdef CUSTOM_MRCP_RESOURCE_NAMES
	options->resource_string_table = custom_resource_string_table;
#endif

	return options;
}

static void destroy_options(openmrcp_server_options_t *options)
{
	if(options->synth_plugin) {
		apr_dso_unload(options->synth_plugin);
		options->synth_plugin = NULL;
	}
	if(options->recog_plugin) {
		apr_dso_unload(options->recog_plugin);
		options->recog_plugin = NULL;
	}
}

void console_cmdline_run();

int main(int argc, const char * const *argv)
{
	apr_pool_t *pool;
	mrcp_server_t *mrcp_server;
	openmrcp_server_options_t *options;
	
	if(apr_initialize() != APR_SUCCESS) {
		apr_terminate();
		return 0;
	}

	if(apr_pool_create(&pool,NULL) != APR_SUCCESS) {
		apr_terminate();
		return 0;
	}

	options = load_options(argc,argv,pool);
	if(options) {
		mrcp_server = openmrcp_server_start(options);
		if(mrcp_server) {
			console_cmdline_run();
			openmrcp_server_shutdown(mrcp_server);
		}

		destroy_options(options);
	}

	apr_pool_destroy(pool);
	apr_terminate();
	return 0;
}
