/*
 * 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 <stdlib.h>
#include <apr_getopt.h>
#include "openmrcp_client.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 int test_case = 0;

static void usage()
{
	printf(
		"\n"
		"Usage:\n"
		"\n"
		"  openmrcpclient [options]\n"
		"\n"
		"  Available options:\n"
		"\n"
		"   -p [--proto] version string  : Set the MRCP vesrion (MRCPv1 or MRCPv2). Default is a MRCPv2\n"
		"\n"
		"   -c [--client] ip:port        : Set the local IP address and SIP port. Default is a 127.0.0.1:8062\n"
		"\n"
		"   -s [--server] ip:port        : Set the remote IP address and SIP port. Default is a 127.0.0.1:8060\n"
		"\n"
		"   -b [--rtp-port-min] port     : Set the min RTP port. Default is a 4000\n"
		"\n"
		"   -e [--rtp-port-max] port     : Set the max RTP port. Default is a 6000\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"
		"   -t [--test] case             : Set the test case [0-console, 1-synthesizer, 2-recognizer]. Default is 0\n"
		"\n");
}

static openmrcp_client_options_t* load_options(int argc, const char * const *argv, apr_pool_t *pool)
{
	openmrcp_client_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 */
		{ "client",       'c', TRUE,  "client ip:port" },   /* -c arg or --client arg */
		{ "server",       's', TRUE,  "server ip:port" },   /* -s arg or --server 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 */
		{ "res-location", 'u', TRUE,  "resource location" },/* -u arg or --res-location arg */
		{ "log",          'l', TRUE,  "log priority" },     /* -l arg or --log arg */
		{ "test",         't', TRUE,  "test case number" }, /* -t arg or --test arg */
		{ "help",         'h', FALSE, "show help" },        /* -h or --help */
		{ NULL, 0, 0, NULL },                               /* end */
	};

	apt_log_priority_set(APT_PRIO_INFO);
	options = openmrcp_client_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 'c':
			{
				char *scope = NULL;
				apr_parse_addr_port(&options->client_ip,&scope,&options->client_port,optarg,pool);
				break;
			}
			case 's':
			{
				char *scope = NULL;
				apr_parse_addr_port(&options->server_ip,&scope,&options->server_port,optarg,pool);
				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 'u':
				if(optarg) {
					options->resource_location = apr_pstrdup(pool,optarg);
				}
				break;
			case 'l':
				if(optarg) {
					apt_log_priority_set(atoi(optarg));
				}
				break;
			case 't':
				if(optarg) {
					test_case = 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;
}

void console_cmdline_run(openmrcp_client_options_t *options, apr_pool_t *pool);
void demo_synthesizer_run(openmrcp_client_options_t *options, apr_pool_t *pool);
void demo_recognizer_run(openmrcp_client_options_t *options, apr_pool_t *pool);

int main(int argc, const char * const *argv)
{
	apr_pool_t *pool;
	openmrcp_client_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) {
		switch(test_case) {
			case 1:
				demo_synthesizer_run(options,pool);
				break;
			case 2:
				demo_recognizer_run(options,pool);
				break;
			default:
				console_cmdline_run(options,pool);
				break;
		}
	}

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