/*
 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
 * Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
 *
 * 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.
 *
 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
 *
 * The Initial Developer of the Original Code is
 * Anthony Minessale II <anthmct@yahoo.com>
 * Portions created by the Initial Developer are Copyright (C)
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Anthony Minessale II <anthmct@yahoo.com>
 * Brian Fertig <brian.fertig@convergencetek.com>
 *
 * php_freeswitch.c -- PHP Module Framework
 *
 */
#include <switch.h>
#ifdef __ICC
#pragma warning (disable:1418)
#endif



#ifdef _MSC_VER
#include <php.h>
#pragma comment(lib, PHP_LIB)
#endif

void fs_core_set_globals(void)
{
	switch_core_set_globals();
}

int fs_core_init(char *path)
{
	switch_status_t status;
	const char *err = NULL;

	if (switch_strlen_zero(path)) {
		path = NULL;
	}

	status = switch_core_init(path, &err);

	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_core_destroy(void)
{
	switch_status_t status;

	status = switch_core_destroy();

	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_loadable_module_init(void)
{
	return switch_loadable_module_init() == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_loadable_module_shutdown(void)
{
	switch_loadable_module_shutdown();
	return 1;
}

int fs_console_loop(void) 
{
	switch_console_loop();
	return 0;
}

void fs_consol_log(char *level_str, char *msg)
{
        switch_log_level_t level = SWITCH_LOG_DEBUG;
        if (level_str) {
                level = switch_log_str2level(level_str);
	}
      
        switch_log_printf(SWITCH_CHANNEL_LOG, level, msg);
}
	
void fs_consol_clean(char *msg)
{
        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, msg);
}

switch_core_session_t *fs_core_session_locate(char *uuid)
{
	switch_core_session_t *session;

	if ((session = switch_core_session_locate(uuid))) {
		switch_core_session_rwunlock(session);
	}

	return session;
}

void fs_channel_answer(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_answer(channel);
}

void fs_channel_pre_answer(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_pre_answer(channel);
}

void fs_channel_hangup(switch_core_session_t *session, char *cause)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_hangup(channel, switch_channel_str2cause(cause));
}

void fs_channel_set_variable(switch_core_session_t *session, char *var, char *val)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_set_variable(channel, var, val);
}

void fs_channel_get_variable(switch_core_session_t *session, char *var)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_get_variable(channel, var);
}

void fs_channel_set_state(switch_core_session_t *session, char *state)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_channel_state_t fs_state = switch_channel_get_state(channel);

	if ((fs_state = switch_channel_name_state(state)) < CS_HANGUP) {
		switch_channel_set_state(channel, fs_state);
	}
}


/*
IVR Routines!  You can do IVR in PHP NOW!
*/

int fs_ivr_play_file(switch_core_session_t *session,
					 char *file,
					 char *timer_name,
					 switch_input_callback_function_t dtmf_callback,
					 void *buf,
					 unsigned int buflen)
{
	switch_status_t status;
	if (switch_strlen_zero(timer_name)) {
		timer_name = NULL;
	}
	
	status = switch_ivr_play_file(session, NULL, file, timer_name, NULL, NULL, 0);
	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_switch_ivr_record_file(switch_core_session_t *session,
						switch_file_handle_t *fh,
						char *file,
						switch_input_callback_function_t dtmf_callback,
						void *buf,
						unsigned int buflen)
{  
	switch_status_t status;
	
        status = switch_ivr_record_file(session, fh, file, dtmf_callback, buf, buflen);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_switch_ivr_sleep(switch_core_session_t *session,
					uint32_t ms)
{
	switch_status_t status;
	status = switch_ivr_sleep(session, ms);
	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_ivr_play_file2(switch_core_session_t *session,
					  char *file)

{
	switch_status_t status;
	
	status = switch_ivr_play_file(session, NULL, file, NULL, NULL, NULL, 0);
	return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}


int fs_switch_ivr_collect_digits_callback (switch_core_session_t *session,
							switch_input_callback_function_t dtmf_callback,
							void *buf,
							unsigned int buflen)
{
        switch_status_t status;

        status = switch_ivr_collect_digits_callback(session, dtmf_callback, buf, buflen);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_switch_ivr_collect_digits_count  	(switch_core_session_t *session,
					char *buf,
					unsigned int buflen,
					unsigned int maxdigits,
					const char *terminators,
					char *terminator,
					unsigned int timeout)  
{
        switch_status_t status;

        status = switch_ivr_collect_digits_count(session, buf, buflen, maxdigits, terminators, terminator, timeout);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

/*int fs_switch_ivr_multi_threaded_bridge   (switch_core_session_t *session,
					switch_core_session_t *peer_session,
					switch_input_callback_function_t dtmf_callback,
					void *session_data,
					void *peer_session_data)  
{
        switch_status_t status;

        status = switch_ivr_multi_threaded_bridge(session, peer_session, dtmf_callback, session_data, peer_session_data);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}
*/

int fs_switch_ivr_originate       (switch_core_session_t *session,
				switch_core_session_t **bleg,
				char *  	bridgeto,
				uint32_t  	timelimit_sec)
				/*const switch_state_handler_table_t *table,
				char *  	cid_name_override,
				char *  	cid_num_override,
				switch_caller_profile_t *caller_profile_override)  */
{

        switch_channel_t *caller_channel;
        switch_core_session_t *peer_session;
        unsigned int timelimit = 60;
        char *var;
		switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;

        caller_channel = switch_core_session_get_channel(session);
        assert(caller_channel != NULL);

        if ((var = switch_channel_get_variable(caller_channel, "call_timeout"))) {
                timelimit = atoi(var);
        }
        
        if (switch_ivr_originate(session, &peer_session, &cause, bridgeto, timelimit, NULL, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel!\n");
                switch_channel_hangup(caller_channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL);
                return;
        } else {
                switch_ivr_multi_threaded_bridge(session, peer_session, NULL, NULL, NULL);
        }


}

int fs_switch_ivr_session_transfer(switch_core_session_t *session,
				char *extension,
				char *dialplan,
				char *context)  
{
        switch_status_t status;

        status = switch_ivr_session_transfer(session,extension,dialplan,context);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}

int fs_switch_ivr_speak_text      (switch_core_session_t *session,
				char *tts_name,
				char *voice_name,
				char *timer_name,
				uint32_t  	rate,
				switch_input_callback_function_t dtmf_callback,
				char *text,
				void *buf,
				unsigned int buflen)  
{
        switch_status_t status;

        status = switch_ivr_speak_text(session,tts_name,voice_name,timer_name,rate,dtmf_callback,text,buf,buflen);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}


/*

*******  CHANNEL STUFF  *******

*/

char* fs_switch_channel_get_variable(switch_channel_t *channel, char *varname)
{
	return switch_channel_get_variable(channel, varname);
}


int fs_switch_channel_set_variable(switch_channel_t *channel, char *varname, char *value)
{
        switch_status_t status;

        status = switch_channel_set_variable(channel, varname, value);
        return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
}  

