/*
 * 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 "mrcp_engine.h"

static mrcp_status_t mrcp_engine_task_msg_signal(mrcp_module_t *module, apt_task_msg_t *task_msg);

/** Init MRCP engine. */
mrcp_status_t mrcp_engine_init(mrcp_engine_t *engine)
{
	engine->module_count = 0;

	return MRCP_STATUS_SUCCESS;
}

/** Destroy MRCP engine. */
mrcp_status_t mrcp_engine_destroy(mrcp_engine_t *engine)
{
	size_t i;
	mrcp_module_t *module;
	for(i=0; i<engine->module_count; i++) {
		module = engine->modules[i];
		if(module && module->method_set && module->method_set->destroy) {
			module->method_set->destroy(module);
		}
	}
	engine->module_count = 0;
	return MRCP_STATUS_SUCCESS;
}

/** Register MRCP module. */
mrcp_status_t mrcp_engine_module_register(mrcp_engine_t *engine, mrcp_module_t *module)
{
	if(engine->module_count >= MRCP_MAX_MODULE_COUNT) {
		return MRCP_STATUS_FAILURE;
	}
	module->state = MODULE_STATE_NONE;
	module->engine = engine;
	module->signal = mrcp_engine_task_msg_signal;
	engine->modules[engine->module_count++] = module;
	return MRCP_STATUS_SUCCESS;
}

/** Open MRCP engine. */
mrcp_module_state_t mrcp_engine_open(mrcp_engine_t *engine)
{
	size_t i;
	mrcp_module_t *module;
	mrcp_module_state_t engine_state = MODULE_STATE_OPENED;
	for(i=0; i<engine->module_count; i++) {
		module = engine->modules[i];
		if(module && module->method_set && module->method_set->open) {
			module->state = module->method_set->open(module);
			if(module->state == MODULE_STATE_NONE) {
				return MODULE_STATE_NONE;
			}
			else if(module->state == MODULE_STATE_OPEN_INPROGRESS) {
				engine_state = MODULE_STATE_OPEN_INPROGRESS;
			}
		}
	}
	return engine_state;
}

/** Close MRCP engine. */
mrcp_module_state_t mrcp_engine_close(mrcp_engine_t *engine)
{
	size_t i;
	mrcp_module_t *module;
	mrcp_module_state_t engine_state = MODULE_STATE_CLOSED;
	for(i=0; i<engine->module_count; i++) {
		module = engine->modules[i];
		if(module && module->method_set && module->method_set->close) {
			if(module->state != MODULE_STATE_NONE && module->state != MODULE_STATE_CLOSED) {
				module->state = module->method_set->close(module);
				if(module->state == MODULE_STATE_CLOSE_INPROGRESS) {
					engine_state = MODULE_STATE_CLOSE_INPROGRESS;
				}
				else if(module->state != MODULE_STATE_CLOSED) {
					return MODULE_STATE_NONE;
				}
			}
		}
	}
	return engine_state;
}

/** Query whether engine is closed. */
mrcp_status_t mrcp_engine_is_closed(mrcp_engine_t *engine)
{
	size_t i;
	mrcp_module_t *module;
	for(i=0; i<engine->module_count; i++) {
		module = engine->modules[i];
		if(module && module->state == MODULE_STATE_CLOSE_INPROGRESS) {
			return MRCP_STATUS_FAILURE;
		}
	}
	return MRCP_STATUS_SUCCESS;
}

static mrcp_status_t mrcp_engine_task_msg_signal(mrcp_module_t *module, apt_task_msg_t *task_msg)
{
	task_msg->msg_handle = module;
	return apt_consumer_task_signal(module->engine->consumer_task,task_msg);
}
