/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
*/

#include <bcmolt_host_api.h>
#include "bcmolt_user_appl_onu_tuning.h"

#define ONU_TUNING_TASK_MSG_Q_SIZE 256

typedef struct
{
    bcmos_msg os_msg;
    bcmolt_auto *ind;
    bcmolt_devid device_id;
} ot_task_msg;

static bcmolt_onu_tuning_context ot_context[BCMTR_MAX_OLTS];


static bcmos_errno onu_tuning_init_task(bcmolt_devid device_id)
{
    bcmos_errno rc;
    bcmos_task_parm task_params = {};
    snprintf(ot_context[device_id].task.name, sizeof(ot_context[device_id].task.name), "user_appl_onu_tuning%u", device_id);
    task_params.name = ot_context[device_id].task.name;
    task_params.priority = TASK_PRIORITY_USER_APPL_ONU_TUNING;
    task_params.core = BCMOS_CPU_CORE_ANY; /* No CPU affinity */
    task_params.init_handler = NULL;
    task_params.data = (long)device_id;
    rc = bcmos_task_create(&ot_context[device_id].task, &task_params);
    BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcmos_task_create()\n");

    return rc;
}

static bcmos_errno onu_tuning_init_module(bcmolt_devid device_id)
{
    /* This value is used inside bcmolt_onu_tuning_module_init for timer owner */
    ot_context[device_id].device = device_id;
    bcmos_module_parm module_params =
    {
        .qparm = { .name = "user_appl_onu_tuning",
		.size = ONU_TUNING_TASK_MSG_Q_SIZE },
    };

    return bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_ONU_TUNING_DEV0 + device_id, &ot_context[device_id].task, &module_params);
}

void bcmolt_onu_tuning_appl_init(bcmolt_devid device_id)
{
    bcmos_errno err;

#ifdef ENABLE_LOG
    char log_name[MAX_DEV_LOG_ID_NAME] = {};
    snprintf(log_name, sizeof(log_name) - 1, "user_appl_onu_tuning%u", device_id);
    ot_context[device_id].log_id = bcm_dev_log_id_register(log_name, DEV_LOG_LEVEL_DEBUG, DEV_LOG_ID_TYPE_BOTH);
#endif

    err = bcmos_mutex_create(&ot_context[device_id].mutex, 0, NULL);
    BUG_ON(err != BCM_ERR_OK);

    err = onu_tuning_init_task(device_id);
    BUG_ON(err != BCM_ERR_OK);

    err = onu_tuning_init_module(device_id);
    BUG_ON(err != BCM_ERR_OK);

}

bcmos_errno bcmolt_onu_tuning_appl_start(bcmolt_devid device_id)
{
    bcmos_errno ret = BCM_ERR_OK;

    bcmos_mutex_lock(&ot_context[device_id].mutex);

    if (ot_context[device_id].is_running)
    {
        BCM_LOG(ERROR, ot_context[device_id].log_id, "ONU tuning application already running on device=%u\n", device_id);
        ret = BCM_ERR_STATE;
        goto exit;
    }

    ot_context[device_id].is_running = BCMOS_TRUE;
    ot_context[device_id].device = device_id;

    BCM_LOG(INFO, ot_context[device_id].log_id, "ONU tuning application started on device=%u\n", device_id);
    ret = BCM_ERR_OK;

exit:
    bcmos_mutex_unlock(&ot_context[device_id].mutex);
    return ret;
}

bcmos_errno bcmolt_onu_tuning_appl_stop(bcmolt_devid device_id)
{
    bcmos_errno ret;

    bcmos_mutex_lock(&ot_context[device_id].mutex);

    if (!ot_context[device_id].is_running)
    {
        ret = BCM_ERR_STATE;
        goto exit;
    }

    ot_context[device_id].is_running = BCMOS_FALSE;
    bcmos_timer_stop(&ot_context[device_id].timer);
    BCM_LOG(INFO, ot_context[device_id].log_id, "ONU tuning application stopped on device=%u\n", device_id);
    ret = BCM_ERR_OK;

exit:
    bcmos_mutex_unlock(&ot_context[device_id].mutex);
    return ret;
}

bcmos_bool bcmolt_onu_tuning_appl_is_running(bcmolt_devid device_id)
{
    bcmos_bool ret;

    bcmos_mutex_lock(&ot_context[device_id].mutex);
    ret = ot_context[device_id].is_running;
    bcmos_mutex_unlock(&ot_context[device_id].mutex);

    return ret;
}

static bcmos_bool bcmolt_onu_tuning_is_interested(bcmolt_auto *ind)
{
    switch (ind->hdr.obj_type)
    {
    case BCMOLT_OBJ_ID_XGPON_ONU:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE:
            return BCMOS_TRUE;
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED:
		   return BCMOS_TRUE;
	    default:
		   break;
        }
        break;
    default:
        break;
    }

    return BCMOS_FALSE;
}

static void bcmolt_onu_tuning_ind_cb(bcmos_module_id module_id, bcmos_msg *os_msg)
{
	ot_task_msg *msg = (ot_task_msg *)os_msg;
	bcmolt_pon_ni pon_ni;
	bcmolt_pon_onu_id onu_id;
	bcmolt_auto *ind = msg->ind;
	bcmos_errno rc;

	switch (msg->ind->hdr.obj_type)
	{
	case BCMOLT_OBJ_ID_XGPON_ONU:
		switch (msg->ind->hdr.subgroup)
		{
			case BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE:
			{
				bcmolt_xgpon_onu_tuning_response *onu_tuning_response = (bcmolt_xgpon_onu_tuning_response *)ind;
				onu_id = onu_tuning_response->key.onu_id;
				pon_ni = onu_tuning_response->key.pon_ni;

				if (onu_tuning_response->data.ack == BCMOS_TRUE && onu_tuning_response->data.result == BCMOLT_RESULT_SUCCESS)
				{
					BCM_LOG(INFO, ot_context[msg->device_id].log_id, "Indication BCMOLT_XGPON_ONU_AUTO_ID_TUNING_RESPONSE handled: PON:%u ONU:%u target_pon_ni=%u\n", pon_ni, onu_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_ni);

					/* start tuning in onu on target pon id */
					bcmolt_xgpon_onu_key key = { .pon_ni = ot_context[msg->device_id].onu_db[onu_id].target_pon_ni, .onu_id = onu_id };
					bcmolt_xgpon_onu_onu_tuning_in onu_tuning_in;

					BCMOLT_OPER_INIT(&onu_tuning_in, xgpon_onu, onu_tuning_in, key);
					rc = bcmolt_oper_submit(msg->device_id, &onu_tuning_in.hdr);
					if (rc != BCM_ERR_OK)
						BCM_LOG(ERROR, ot_context[msg->device_id].log_id, "ONU=%u tuning in to PON=%u failed\n", onu_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_ni);
				}

				break;
			}
			case BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED:
			{
				bcmolt_xgpon_onu_onu_tuning_in_completed *onu_tuning_in_completed = (bcmolt_xgpon_onu_onu_tuning_in_completed *)ind;
				onu_id = onu_tuning_in_completed->key.onu_id;
				pon_ni = onu_tuning_in_completed->key.pon_ni;
				if (onu_tuning_in_completed->data.result == BCMOLT_RESULT_SUCCESS)
				{
					BCM_LOG(INFO, ot_context[msg->device_id].log_id, "Indication BCMOLT_XGPON_ONU_AUTO_ID_ONU_TUNING_IN_COMPLETED handled: PON:%u ONU:%u\n", pon_ni, onu_id);

					/* start tuning out onu on source pon id */
					bcmolt_xgpon_onu_key key = { .pon_ni = ot_context[msg->device_id].onu_db[onu_id].source_pon_ni, .onu_id = onu_id };
					bcmolt_xgpon_onu_onu_tuning_out onu_tuning_out;

					BCMOLT_OPER_INIT(&onu_tuning_out, xgpon_onu, onu_tuning_out, key);
					BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, target_ds_pon_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_id);
					BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, target_us_pon_id, ot_context[msg->device_id].onu_db[onu_id].target_pon_id);
					BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, time_to_switch, 1000);
					BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, rollback, BCMOS_FALSE);
					BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, status, BCMOLT_STATUS_OFF);
					rc = bcmolt_oper_submit(msg->device_id, &onu_tuning_out.hdr);
					if (rc != BCM_ERR_OK)
						BCM_LOG(ERROR, ot_context[msg->device_id].log_id, "ONU=%u tuning out from PON=%u failed\n", onu_id, ot_context[msg->device_id].onu_db[onu_id].source_pon_ni);
				}
				break;
			}
			default:
				break;
		}
	break;
	default:
		break;
	}

	/* free the cloned indication since we're done processing it */
	bcmolt_msg_free(&msg->ind->hdr);
	/* free the internal OS message handle */
	bcmos_free(os_msg);
}

bcmos_errno bcmolt_onu_tuning_process_ind(bcmolt_devid device_id, bcmolt_auto *ind)
{
    bcmos_errno err;
    bcmolt_msg *ind_clone = NULL;

    /* if the application isn't running, don't listen to any indications */
    if (!bcmolt_onu_tuning_appl_is_running(device_id))
        return BCM_ERR_OK;

    /* check to see if we have a handler for this type of indication */
    if (!bcmolt_onu_tuning_is_interested(ind))
        return BCM_ERR_OK;

    /* clone the indication into newly-allocated memory so we can handle it after the original message has been freed */
    err = bcmolt_msg_clone(&ind_clone, &ind->hdr);
    if (err != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, ot_context[device_id].log_id, "Indication clone failed: %s\n", bcmos_strerror(err));
        return err;
    }

    /* send the clone to the internal task's message queue */
    ot_task_msg *msg = bcmos_calloc(sizeof(*msg));
    if (msg == NULL)
    {
        BCM_LOG(ERROR, ot_context[device_id].log_id, "Message calloc failed: %s\n", bcmos_strerror(err));
        bcmolt_msg_free(ind_clone);
        return BCM_ERR_NOMEM;
    }
    msg->os_msg.handler = bcmolt_onu_tuning_ind_cb;
    msg->os_msg.release = bcmolt_os_msg_release_cb;
    msg->device_id = device_id;
    msg->ind = (bcmolt_auto *)ind_clone;

    err = bcmos_msg_send_to_module(TASK_PRIORITY_USER_APPL_ONU_TUNING + device_id, &msg->os_msg, 0);
    if (err != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, ot_context[device_id].log_id, "Message send failed: %s\n", bcmos_strerror(err));
        bcmolt_msg_free(ind_clone);
        return err;
    }

    return BCM_ERR_OK;
}

bcmos_errno onu_tuning_update_onu_db (bcmolt_devid device_id, bcmolt_xgpon_onu_id onu_id, bcmolt_pon_ni source_pon_ni, bcmolt_pon_ni target_pon_ni, bcmolt_pon_id target_pon_id, bcmos_bool rollback)
{
	bcmos_errno ret;
	 bcmos_mutex_lock(&ot_context[device_id].mutex);

	    if (!ot_context[device_id].is_running)
	    {
	        ret = BCM_ERR_STATE;
	        goto exit;
	    }
	    ot_context[device_id].onu_db[onu_id].target_pon_ni = target_pon_ni;
	    ot_context[device_id].onu_db[onu_id].source_pon_ni = source_pon_ni;
	    ot_context[device_id].onu_db[onu_id].target_pon_id = target_pon_id;
	    ot_context[device_id].onu_db[onu_id].rollback = rollback;
	    ret = BCM_ERR_OK;

exit:
	bcmos_mutex_unlock(&ot_context[device_id].mutex);
	return ret;
}
