/*
<: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 <bcmos_system.h>
#include <bcmolt_api.h>
#include <bcmolt_msg_pack.h>
#include <bcmolt_model_types.h>
#include <bcm_dev_log.h>
#include "bcmolt_user_appl_ps.h"
#include "bcmolt_user_appl_ps_internal.h"

#ifndef SIMULATION_BUILD
#include <bcmolt_board.h>
#endif

#define PS_DEFAULT_MAX_PAIRS 16
#define PS_TASK_MSG_Q_SIZE 64

typedef struct
{
    bcmolt_ps_pair pair;
    bcmos_bool is_valid;
} ps_pair_state;

typedef struct
{
    bcmos_bool is_running;
    bcmolt_ps_global_cfg cfg;
    ps_pair_state *pairs;
    uint32_t switch_start_time_us;
} ps_global_state;

typedef struct
{
    bcmos_msg os_msg;
    bcmolt_ps_pon pon;
    bcmolt_auto *ind;
} ps_task_msg;

typedef enum
{
    PS_PON_MODE_INVALID,
    PS_PON_MODE_GPON,
    PS_PON_MODE_EPON,
    PS_PON_MODE_XGPON,
} ps_pon_mode;

static ps_global_state ps_state = {};
static bcmos_mutex ps_mutex;
static bcmos_task ps_task;

#ifdef ENABLE_LOG
static dev_log_id ps_log_id;
dev_log_id ps_get_log_id(void)
{
    return ps_log_id;
}
#endif

static inline bcmos_bool ps_pon_equal(const bcmolt_ps_pon *a, const bcmolt_ps_pon *b)
{
    return a->device_id == b->device_id && a->pon_id == b->pon_id;
}

static inline bcmos_bool ps_pair_equal(const bcmolt_ps_pair *a, const bcmolt_ps_pair *b)
{
    return ps_pon_equal(&a->standby, &b->standby) && ps_pon_equal(&a->working, &b->working);
}

static bcmos_errno bcmolt_ps_pon_pair_get(const bcmolt_ps_pon *pon, bcmolt_ps_pair **pair)
{
    uint16_t i;

    if (!ps_state.is_running)
    {
        *pair = NULL;
        PS_ERR("PS application not running\n");
        return BCM_ERR_STATE;
    }

    for (i = 0; i < ps_state.cfg.max_num_pairs; i++)
    {
        if (ps_state.pairs[i].is_valid)
        {
            if (ps_pon_equal(pon, &ps_state.pairs[i].pair.standby) ||
                ps_pon_equal(pon, &ps_state.pairs[i].pair.working))
            {
                *pair = &ps_state.pairs[i].pair;
                return BCM_ERR_OK;
            }
        }
    }

    return BCM_ERR_NOENT;
}

static bcmos_errno ps_init_task(void)
{
    bcmos_task_parm task_params =
    {
        .name = "user_appl_ps",
        .priority = TASK_PRIORITY_USER_APPL_PS,
        .core = BCMOS_CPU_CORE_ANY, /* No CPU affinity */
        .init_handler = NULL
    };

    return bcmos_task_create(&ps_task, &task_params);
}

static bcmos_errno ps_init_module(void)
{
    bcmos_module_parm module_params =
    {
        .qparm = { .name = "user_appl_ps", .size = PS_TASK_MSG_Q_SIZE }
    };

    return bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_PS, &ps_task, &module_params);
}

static ps_pon_mode ps_pon_mode_get(bcmolt_devid dev)
{
    bcmos_errno err;
    bcmolt_system_mode system_mode;

    err = bcmolt_system_mode_get(dev, &system_mode);
    if (err != BCM_ERR_OK)
    {
        return PS_PON_MODE_INVALID;
    }
    switch (system_mode)
    {
    case BCMOLT_SYSTEM_MODE_GPON__4_X:
    case BCMOLT_SYSTEM_MODE_GPON__8_X:
    case BCMOLT_SYSTEM_MODE_GPON__16_X:
        return PS_PON_MODE_GPON;
    case BCMOLT_SYSTEM_MODE_EPON__16_X:
    case BCMOLT_SYSTEM_MODE_EPON__8_X:
    case BCMOLT_SYSTEM_MODE_EPON__4_X:
    case BCMOLT_SYSTEM_MODE_EPON__8_X_COEXISTENCE_TDMA:
    case BCMOLT_SYSTEM_MODE_EPON__4_X_COEXISTENCE_TDMA:
    case BCMOLT_SYSTEM_MODE_EPON__8_X_10_G:
    case BCMOLT_SYSTEM_MODE_EPON__4_X_10_G:
    case BCMOLT_SYSTEM_MODE_EPON__2_X_10_G:
        return PS_PON_MODE_EPON;
    case BCMOLT_SYSTEM_MODE_XGPON_1__4_X:
    case BCMOLT_SYSTEM_MODE_XGPON_1__8_X:
    case BCMOLT_SYSTEM_MODE_XGS__2_X_10_G:
    case BCMOLT_SYSTEM_MODE_NGPON2__2_X_10_G:
        return PS_PON_MODE_XGPON;
    default:
        return PS_PON_MODE_INVALID;
    }
}

static void ps_handle_msg(bcmos_module_id module_id, bcmos_msg *os_msg)
{
    ps_task_msg *msg = (ps_task_msg *)os_msg;
    bcmos_errno err;

    /* process the indication */
    if (msg->ind->hdr.obj_type == BCMOLT_OBJ_ID_DEVICE || msg->ind->hdr.obj_type == BCMOLT_OBJ_ID_DEBUG)
    {
        /* there's no need to mirror device-level indications */
        err = BCM_ERR_OK;
    }
    else
    {
        switch (ps_pon_mode_get(msg->pon.device_id))
        {
        case PS_PON_MODE_GPON:
            err = ps_process_ind_gpon(&msg->pon, msg->ind);
            break;
        case PS_PON_MODE_EPON:
            err = ps_process_ind_epon(&msg->pon, msg->ind);
            break;
        case PS_PON_MODE_XGPON:
            err = ps_process_ind_xgpon(&msg->pon, msg->ind);
            break;
        default:
            err = BCM_ERR_STATE; /* not a supported system mode */
            break;
        }
    }

    if (err != BCM_ERR_OK)
    {
        bcmolt_auto *ind = msg->ind;

        PS_ERR("Error processing indication (obj_type=%u, subgroup=%u): %s\n", ind->hdr.obj_type, ind->hdr.subgroup, bcmos_strerror(err));
    }

    /* 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);
}

void bcmolt_ps_appl_init(void)
{
    bcmos_errno err;

#ifdef ENABLE_LOG
    ps_log_id = bcm_dev_log_id_register("user_appl_ps", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
#endif

    err = bcmos_mutex_create(&ps_mutex, 0, NULL);
    BUG_ON(err != BCM_ERR_OK);

    err = ps_init_task();
    BUG_ON(err != BCM_ERR_OK);

    err = ps_init_module();
    BUG_ON(err != BCM_ERR_OK);
}

bcmos_errno bcmolt_ps_appl_start(const bcmolt_ps_global_cfg *cfg)
{
    bcmos_mutex_lock(&ps_mutex);

    if (ps_state.is_running)
    {
        bcmos_mutex_unlock(&ps_mutex);
        PS_ERR("PS application already running\n");
        return BCM_ERR_STATE;
    }

    ps_state.cfg = *cfg;
    ps_state.cfg.max_num_pairs = (ps_state.cfg.max_num_pairs == 0) ? PS_DEFAULT_MAX_PAIRS : ps_state.cfg.max_num_pairs;
    ps_state.pairs = bcmos_calloc(sizeof(*ps_state.pairs) * ps_state.cfg.max_num_pairs);
    if (ps_state.pairs == NULL)
    {
        BCM_MEMZERO_STRUCT(&ps_state);
        bcmos_mutex_unlock(&ps_mutex);
        PS_ERR("memory allocation failed\n");
        return BCM_ERR_NOMEM;
    }

    ps_state.is_running = BCMOS_TRUE;

    bcmos_mutex_unlock(&ps_mutex);
    PS_INFO("PS application started\n");
    return BCM_ERR_OK;
}

bcmos_errno bcmolt_ps_appl_stop(void)
{
    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        bcmos_mutex_unlock(&ps_mutex);
        PS_ERR("PS application not running\n");
        return BCM_ERR_STATE;
    }

    ps_state.is_running = BCMOS_FALSE;

    bcmos_free(ps_state.pairs);
    BCM_MEMZERO_STRUCT(&ps_state);

    bcmos_mutex_unlock(&ps_mutex);
    PS_INFO("PS application stopped\n");
    return BCM_ERR_OK;
}

bcmos_bool bcmolt_ps_appl_is_running(void)
{
    bcmos_bool ret;
    bcmos_mutex_lock(&ps_mutex);
    ret = ps_state.is_running;
    bcmos_mutex_unlock(&ps_mutex);
    return ret;
}

bcmos_errno bcmolt_ps_global_cfg_get(bcmolt_ps_global_cfg *cfg)
{
    bcmos_errno err;
    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        PS_ERR("PS application not running\n");
        err = BCM_ERR_STATE;
    }
    else
    {
        *cfg = ps_state.cfg;
        err = BCM_ERR_OK;
    }

    bcmos_mutex_unlock(&ps_mutex);
    return err;
}

bcmos_errno bcmolt_ps_global_cfg_update(const bcmolt_ps_global_cfg *cfg)
{
    bcmos_errno err;
    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        PS_ERR("PS application not running\n");
        err = BCM_ERR_STATE;
    }
    else if (cfg->max_num_pairs != ps_state.cfg.max_num_pairs)
    {
        PS_ERR("cannot change max number of protected pairs while running\n");
        err = BCM_ERR_PARM;
    }
    else
    {
        ps_state.cfg = *cfg;
        err = BCM_ERR_OK;
    }

    bcmos_mutex_unlock(&ps_mutex);
    return err;
}

bcmos_errno bcmolt_ps_pairs_get(uint16_t array_len, bcmolt_ps_pair *pairs, uint16_t *num_written)
{
    bcmos_errno err;
    uint16_t i;

    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        PS_ERR("PS application not running\n");
        err = BCM_ERR_STATE;
    }
    else
    {
        *num_written = 0;
        err = BCM_ERR_OK;
        for (i = 0; i < ps_state.cfg.max_num_pairs; i++)
        {
            if (ps_state.pairs[i].is_valid)
            {
                if (*num_written == array_len)
                {
                    PS_ERR("array size too small to collect all pairs\n");
                    err = BCM_ERR_PARM;
                    break;
                }
                pairs[*num_written] = ps_state.pairs[i].pair;
                (*num_written)++;
            }
        }
    }

    bcmos_mutex_unlock(&ps_mutex);
    return err;
}

bcmos_errno bcmolt_ps_pair_add(const bcmolt_ps_pair *pair)
{
    uint16_t i;
    bcmos_errno err;

    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        PS_ERR("PS application not running\n");
        err = BCM_ERR_STATE;
    }
    else if (ps_pon_equal(&pair->working, &pair->standby))
    {
        PS_ERR("A PON cannot protect itself\n");
        err = BCM_ERR_PARM;
    }
    else
    {
        err = BCM_ERR_OK;
        for (i = 0; i < ps_state.cfg.max_num_pairs; i++)
        {
            if (ps_state.pairs[i].is_valid &&
                (ps_pon_equal(&pair->working, &ps_state.pairs[i].pair.working) ||
                ps_pon_equal(&pair->working, &ps_state.pairs[i].pair.standby) ||
                ps_pon_equal(&pair->standby, &ps_state.pairs[i].pair.working) ||
                ps_pon_equal(&pair->standby, &ps_state.pairs[i].pair.standby)))
            {
                PS_ERR("One of the PONs was already present in an existing pair\n");
                err = BCM_ERR_ALREADY;
                break;
            }
        }

        if (err == BCM_ERR_OK)
        {
            err = BCM_ERR_NORES;
            for (i = 0; i < ps_state.cfg.max_num_pairs; i++)
            {
                if (!ps_state.pairs[i].is_valid)
                {
                    ps_state.pairs[i].pair = *pair;
                    ps_state.pairs[i].is_valid = BCMOS_TRUE;
                    err = BCM_ERR_OK;
                    break;
                }
            }
            if (err == BCM_ERR_NORES)
            {
                PS_ERR("Not enough memory available to add pair\n");
            }
        }
    }

    bcmos_mutex_unlock(&ps_mutex);
    return err;
}

bcmos_errno bcmolt_ps_pon_remove(const bcmolt_ps_pon *pon)
{
    uint16_t i;
    bcmos_errno err;

    bcmos_mutex_lock(&ps_mutex);

    if (!ps_state.is_running)
    {
        PS_ERR("PS application not running\n");
        err = BCM_ERR_STATE;
    }
    else
    {
        err = BCM_ERR_NOENT;
        for (i = 0; i < ps_state.cfg.max_num_pairs; i++)
        {
            if (ps_state.pairs[i].is_valid &&
                (ps_pon_equal(pon, &ps_state.pairs[i].pair.working) ||
                ps_pon_equal(pon, &ps_state.pairs[i].pair.standby)))
            {
                ps_state.pairs[i].is_valid = BCMOS_FALSE;
                err = BCM_ERR_OK;
                break;
            }
        }
        if (err == BCM_ERR_NOENT)
        {
            PS_ERR("Specified PON not found\n");
        }
    }

    bcmos_mutex_unlock(&ps_mutex);
    return err;
}

bcmos_errno bcmolt_ps_pon_state_get(const bcmolt_ps_pon *pon, bcmolt_ps_pon_state *state, bcmolt_ps_pon *partner)
{
    bcmos_errno err;
    bcmolt_ps_pair *pair;

    bcmos_mutex_lock(&ps_mutex);
    err = bcmolt_ps_pon_pair_get(pon, &pair);
    bcmos_mutex_unlock(&ps_mutex);

    if (err == BCM_ERR_OK)
    {
        if (ps_pon_equal(pon, &pair->standby))
        {
            *state = BCMOLT_PS_PON_STATE_STANDBY;
            *partner = pair->working;
        }
        else
        {
            *state = BCMOLT_PS_PON_STATE_WORKING;
            *partner = pair->standby;
        }
        return BCM_ERR_OK;
    }
    else if (err == BCM_ERR_NOENT)
    {
        *state = BCMOLT_PS_PON_STATE_UNASSOCIATED;
        return BCM_ERR_OK;
    }
    else
    {
        return err;
    }
}

bcmos_errno bcmolt_ps_process_ind(const bcmolt_ps_pon *pon, bcmolt_auto *ind)
{
    bcmos_errno err;
    bcmolt_msg *ind_clone = NULL;

    if (!bcmolt_ps_appl_is_running())
    {
        return BCM_ERR_OK;
    }

    /* Make a copy of all indications received so they can be handled later asynchronously. We don't validate PON state
     * here since it might change before we get around to handling it.
     *
     * Note that this could be optimized to filter out indications that aren't relevant for protection switching before
     * copying them, but this is left out for simplicity. */
    err = bcmolt_msg_clone(&ind_clone, &ind->hdr);
    if (err != BCM_ERR_OK)
    {
        PS_ERR("Indication clone failed: %s\n", bcmos_strerror(err));
        return err;
    }

    /* send this indication to the internal task's message queue to be processed */
    ps_task_msg *msg = bcmos_calloc(sizeof(*msg));
    if (msg == NULL)
    {
        PS_ERR("Message calloc failed\n");
        bcmolt_msg_free(ind_clone);
        return BCM_ERR_NOMEM;
    }

    msg->os_msg.handler = ps_handle_msg;
    msg->os_msg.release = bcmolt_os_msg_release_cb;
    msg->pon = *pon;
    msg->ind = (bcmolt_auto *)ind_clone;

    err = bcmos_msg_send_to_module(BCMOS_MODULE_ID_USER_APPL_PS, &msg->os_msg, 0);
    if (err != BCM_ERR_OK)
    {
        PS_ERR("Message send failed: %s\n", bcmos_strerror(err));
        return err;
    }

    return BCM_ERR_OK;
}

static bcmos_errno bcmolt_ps_change_pon_to_standby(const bcmolt_ps_pon *pon)
{
    bcmos_errno err;

    PS_INFO("Switching PON <%d:%d> working->standby\n", pon->device_id, pon->pon_id);
    switch (ps_pon_mode_get(pon->device_id))
    {
    case PS_PON_MODE_GPON:
        err = ps_move_to_standby_gpon(pon);
        break;
    case PS_PON_MODE_EPON:
        err = ps_move_to_standby_epon(pon);
        break;
    case PS_PON_MODE_XGPON:
        err = ps_move_to_standby_xgpon(pon);
        break;
    default:
        err = BCM_ERR_STATE; /* not a supported system mode */
        break;
    }
    if (err != BCM_ERR_OK)
    {
        PS_ERR("<%d:%d> working->standby API failed: %s\n", pon->device_id, pon->pon_id, bcmos_strerror(err));
    }
    return err;
}

static bcmos_errno bcmolt_ps_change_pon_to_working(const bcmolt_ps_pon *pon)
{
    bcmos_errno err;

    PS_INFO("Switching PON <%d:%d> standby->working\n", pon->device_id, pon->pon_id);
    switch (ps_pon_mode_get(pon->device_id))
    {
    case PS_PON_MODE_GPON:
        err = ps_move_to_working_gpon(pon);
        break;
    case PS_PON_MODE_EPON:
        err = ps_move_to_working_epon(pon);
        break;
    case PS_PON_MODE_XGPON:
        err = ps_move_to_working_xgpon(pon);
        break;
    default:
        err = BCM_ERR_STATE; /* not a supported system mode */
        break;
    }
    if (err != BCM_ERR_OK)
    {
        PS_ERR("<%d:%d> standby->working API failed: %s\n", pon->device_id, pon->pon_id, bcmos_strerror(err));
    }
    return err;
}

static bcmos_errno bcmolt_ps_disable_tx_optics(const bcmolt_ps_pon *pon)
{
    PS_INFO("Disabling TRX for PON <%d:%d:%d>\n", pon->device_id, pon->pon_id, pon->transceiver_id);

    /* This disables the TX optical channel on a given PON port on the BCM68620 SVK board.
       For other boards, this must be changed to match the board design. */
#ifndef SIMULATION_BUILD
    return bcm_board_trx_enable(pon->transceiver_id, BCMOS_FALSE);
#else
    return BCM_ERR_OK;
#endif
}

static bcmos_errno bcmolt_ps_enable_tx_optics(const bcmolt_ps_pon *pon)
{
#ifndef SIMULATION_BUILD
    bcmos_errno ret;
#endif

    PS_INFO("Enabling TRX for PON <%d:%d:%d>\n", pon->device_id, pon->pon_id, pon->transceiver_id);

    /* This enables the TX optical channel on a given PON port on the BCM68620 SVK board.
       For other boards, this must be changed to match the board design. */
#ifndef SIMULATION_BUILD
    ret = bcm_board_trx_enable(pon->transceiver_id, BCMOS_TRUE);
    bcmos_usleep(ps_state.cfg.trx_warming_delay);
    return ret;
#else
    return BCM_ERR_OK;
#endif
}

bcmos_errno bcmolt_ps_switch_perform(const bcmolt_ps_pon *pon)
{
    bcmos_errno err;
    bcmolt_ps_pair *pair;
    bcmolt_ps_pon temp_pon;

    bcmos_mutex_lock(&ps_mutex);
    ps_state.switch_start_time_us = bcmos_timestamp();
    err = bcmolt_ps_pon_pair_get(pon, &pair);
    bcmos_mutex_unlock(&ps_mutex);

    if (err != BCM_ERR_OK)
    {
        goto exit;
    }

    if (ps_state.cfg.switch_sequence == BCMOLT_PS_SWITCH_SEQUENCE_TRX_FIRST)
    {
        /* step 1: disable optical TX channel of the working PON */
        err = bcmolt_ps_disable_tx_optics(&pair->working);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 2: enable optical TX channel of the standby PON */
        err = bcmolt_ps_enable_tx_optics(&pair->standby);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 3: change the standby PON state to working */
        err = bcmolt_ps_change_pon_to_working(&pair->standby);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 4: change the working PON state to standby */
        err = bcmolt_ps_change_pon_to_standby(&pair->working);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }
    }
    else /* ps_state.cfg.switch_sequence == BCMOLT_PS_SWITCH_SEQUENCE_STANDARD */
    {
        /* step 1: change the working PON state to standby */
        err = bcmolt_ps_change_pon_to_standby(&pair->working);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 2: disable optical TX channel of the working PON */
        err = bcmolt_ps_disable_tx_optics(&pair->working);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 3: enable optical TX channel of the standby PON */
        err = bcmolt_ps_enable_tx_optics(&pair->standby);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }

        /* step 4: change the standby PON state to working */
        err = bcmolt_ps_change_pon_to_working(&pair->standby);
        if (err != BCM_ERR_OK)
        {
            goto exit;
        }
    }

    /* step 5: update internal database for new PON states */
    bcmos_mutex_lock(&ps_mutex);
    temp_pon = pair->working;
    pair->working = pair->standby;
    pair->standby = temp_pon;
    bcmos_mutex_unlock(&ps_mutex);

exit:
    if (err == BCM_ERR_OK)
    {
        PS_INFO(
            "<%d:%d> switchover started successfully (<%d:%d> is now standby)\n",
            pair->working.device_id,
            pair->working.pon_id,
            pair->standby.device_id,
            pair->standby.pon_id);
    }
    else if (pair)
    {
        PS_INFO(
            "<%d:%d> switchover encountered an error: %s\n",
            pair->working.device_id,
            pair->working.pon_id,
            bcmos_strerror(err));
    }

    return err;
}

uint32_t ps_get_last_switch_start_time_us(void)
{
    uint32_t ret;
    bcmos_mutex_lock(&ps_mutex);
    ret = ps_state.switch_start_time_us;
    bcmos_mutex_unlock(&ps_mutex);
    return ret;
}
