/*
<: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"
#include "bcmolt_user_appl_onu_tuning_cli.h"
#include <bcmolt_dev_selector.h>

static bcmos_errno bcmolt_user_appl_onu_tuning_cli_create(bcmcli_entry *top_dir);

static bcmcli_entry *onu_tuning_cli_dir;
static bcmcli_entry *onu_tuning_cli_top_dir;
static bcmos_bool onu_tuning_is_registered;

/* Destroy CLI commands */
static void onu_tuning_cli_destroy(void)
{
    if (onu_tuning_cli_dir)
    {
        bcmcli_token_destroy(onu_tuning_cli_dir);
        onu_tuning_cli_dir = NULL;
    }
}

/* Current device change indication */
static void bcmolt_user_appl_onu_tuning_device_change_ind(bcmcli_session *session, bcmolt_devid dev)
{
    bcmolt_system_mode system_mode;
    bcmos_errno err = bcmolt_system_mode_get(dev, &system_mode);

    if (err != BCM_ERR_OK)
    {
        bcmcli_session_print(session, "Error device Id\n");
        return;
    }

    if (system_mode == BCMOLT_SYSTEM_MODE_NGPON2__2_X_10_G)
    {
        bcmcli_session_print(session, "Building onu_tuning CLI for device %d\n", dev);

        err = bcmolt_user_appl_onu_tuning_cli_create(onu_tuning_cli_top_dir);
        if (err)
        {
            bcmcli_session_print(session, "Error building onu_tuning CLI\n");
        }
    }
    else
    {
    	onu_tuning_cli_destroy();
    }
}

static bcmos_errno onu_tuning_cmd_start(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms)
{
    return bcmolt_onu_tuning_appl_start(current_device);
}

static bcmos_errno onu_tuning_cmd_stop(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms)
{
    return bcmolt_onu_tuning_appl_stop(current_device);
}

static bcmos_errno onu_handover_cmd(bcmcli_session *session, const bcmcli_cmd_parm parms[], uint16_t n_parms)
{
	bcmolt_xgpon_onu_id onu_id;
	bcmolt_pon_ni target_pon_ni;
	bcmolt_pon_ni source_pon_ni;
	uint32_t target_pon_administrative_label;
	uint8_t target_pon_dwlch_id;
	uint32_t time_to_switch;        /* Time to switch in ms */
	bcmcli_cmd_parm *rollback_parm = bcmcli_find_named_parm(session, "rollback");
	bcmos_bool rollback;
	bcmos_errno rc = BCM_ERR_OK;
	bcmolt_pon_id target_pon_id;


	source_pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "source_pon_ni")->value.unumber;
	target_pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "target_pon_ni")->value.unumber;
	onu_id = (bcmolt_pon_onu_id)bcmcli_find_named_parm(session, "onu")->value.unumber;
	target_pon_administrative_label = (uint32_t)bcmcli_find_named_parm(session, "target_pon_id_administrative_label")->value.unumber;
	target_pon_dwlch_id = (uint8_t)bcmcli_find_named_parm(session, "target_pon_id_dwlch_id")->value.unumber;
	target_pon_id.administrative_label = target_pon_administrative_label;
	target_pon_id.dwlch_id = target_pon_dwlch_id;
	time_to_switch = (uint32_t)bcmcli_find_named_parm(session, "time_to_switch")->value.unumber;

	if (rollback_parm->value.unumber == 0)
		rollback = BCMOS_FALSE;
	else
		rollback = BCMOS_TRUE;
	/* update tuning in parameters in data base */
	onu_tuning_update_onu_db(current_device, onu_id, source_pon_ni, target_pon_ni, target_pon_id, rollback);

	bcmcli_session_print(session, "Tuning out ONU=%u source_pon_ni=%u target_pon_ni=%u \n", onu_id, source_pon_ni, target_pon_ni);

	/* start tuning out onu on source pon id */
	bcmolt_xgpon_onu_key key = { .pon_ni = 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, target_pon_id);
	BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, target_us_pon_id, target_pon_id);
	BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, time_to_switch, time_to_switch);
	BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, rollback, BCMOS_TRUE);
	BCMOLT_OPER_PROP_SET(&onu_tuning_out, xgpon_onu, onu_tuning_out, status, BCMOLT_STATUS_ON);
	rc = bcmolt_oper_submit(current_device, &onu_tuning_out.hdr);
	if (rc != BCM_ERR_OK)
		bcmcli_session_print(session, "ONU=%u tuning out from PON=%u failed\n", onu_id, source_pon_ni);

	return BCM_ERR_OK;
}

bcmos_errno bcmolt_user_appl_onu_tuning_cli_init(bcmcli_entry *top_dir)
{
    bcmos_errno err = BCM_ERR_OK;

    /* Subscribe for device change indication */
    if (!onu_tuning_is_registered)
    {
    	onu_tuning_is_registered = BCMOS_TRUE;

        err = bcmolt_dev_sel_ind_register(bcmolt_user_appl_onu_tuning_device_change_ind);
    }
    return err ? err : bcmolt_user_appl_onu_tuning_cli_create(top_dir);
}

static bcmos_errno bcmolt_user_appl_onu_tuning_cli_create(bcmcli_entry *top_dir)
{
    bcmcli_entry *dir;

    if (bcmcli_dir_find(top_dir, "onu_tuning"))
    {
        return BCM_ERR_OK;
    }

    dir = bcmcli_dir_add(
        top_dir,
        "onu_tuning",
        "NGPON2 ONU tuning user application",
        BCMCLI_ACCESS_ADMIN,
        NULL);
    BCMOS_CHECK_RETURN_ERROR(!dir, BCM_ERR_NOMEM);

    BCMCLI_MAKE_CMD_NOPARM(dir, "start", "Start ONU tuning application", onu_tuning_cmd_start);

    BCMCLI_MAKE_CMD_NOPARM(dir, "stop", "Stop ONU tuning application", onu_tuning_cmd_stop);

    BCMCLI_MAKE_CMD(dir, "onu_handover", "ONU handover", onu_handover_cmd,
		BCMCLI_MAKE_PARM("onu", "ONU ID", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM("source_pon_ni", "Source PON_NI", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM("target_pon_ni", "Target PON_NI", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM("target_pon_id_administrative_label", "Target PON ID Administrative label", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM("target_pon_id_dwlch_id", "Target PON ID Channel id", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM("time_to_switch", "Time_To_Switch", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
		BCMCLI_MAKE_PARM_ENUM("rollback", "Rollback", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_OPTIONAL));


    onu_tuning_cli_dir = dir;
    onu_tuning_cli_top_dir = top_dir;

    return BCM_ERR_OK;
}
