/*
<: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 <bcmtr_interface.h>
#include <bcmtr_header.h>
#include <bcmtr_transport_cli.h>
#include <bcmolt_api.h>
#include <bcmtr_debug.h>
#ifdef ENABLE_CLI
#include <bcmcli.h>
#endif
#include "bcmolt_api_proxy.h"
#ifdef ENABLE_LOG
#include "bcm_dev_log.h"
#endif

/* Statistics */
typedef struct proxy_stats
{
    unsigned long rx_packets;
    unsigned long rx_bytes;
    unsigned long tx_packets;
    unsigned long tx_bytes;
    unsigned long rx_errors;
    unsigned long tx_errors;
    unsigned long unpack_errors;
    unsigned long pack_errors;
    unsigned long msg_errors;
} proxy_stats;

typedef struct proxy_control_block
{
    bcmos_task proxy_rx_task;
    struct sockaddr_in client;
    uint32_t proxy_port;
    int device_id;
    int client_socket;
    bcmos_bool is_running;
    char *on_ready_cmd;

    /* the maximum amount of memory that could possibly by used by all variable-sized lists within a GET request */
#define DYNAMIC_LIST_BUFFER_SIZE (32 * 1024)
    uint8_t dynamic_list_buffer[DYNAMIC_LIST_BUFFER_SIZE];

    dev_log_id proxy_log;

    proxy_stats stats;
} proxy_control_block;

/* Per device proxy control block */
static proxy_control_block proxy_data[BCMTR_MAX_OLTS];
static bcmos_bool is_first_proxy = BCMOS_TRUE;

#ifdef ENABLE_CLI
/*/proxy/stats command handler
*/
static bcmos_errno _proxy_stats_cmd(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    int device = (int)parm[0].value.number;

    if (device >= BCMTR_MAX_OLTS)
        return BCM_ERR_RANGE;

    bcmcli_print(session, "%-16s: %lu\n", "rx_packets", proxy_data[device].stats.rx_packets);
    bcmcli_print(session, "%-16s: %lu\n", "rx_bytes", proxy_data[device].stats.rx_bytes);
    bcmcli_print(session, "%-16s: %lu\n", "tx_packets", proxy_data[device].stats.tx_packets);
    bcmcli_print(session, "%-16s: %lu\n", "tx_bytes", proxy_data[device].stats.tx_bytes);
    bcmcli_print(session, "%-16s: %lu\n", "rx_errors", proxy_data[device].stats.rx_errors);
    bcmcli_print(session, "%-16s: %lu\n", "tx_errors", proxy_data[device].stats.tx_errors);
    bcmcli_print(session, "%-16s: %lu\n", "unpack_errors", proxy_data[device].stats.unpack_errors);
    bcmcli_print(session, "%-16s: %lu\n", "pack_errors", proxy_data[device].stats.pack_errors);
    bcmcli_print(session, "%-16s: %lu\n", "msg_errors", proxy_data[device].stats.msg_errors);
    memset(&proxy_data[device].stats, 0, sizeof(proxy_stats));

    return BCM_ERR_OK;
}
#endif /* #ifdef ENABLE_CLI */

static bcmos_errno _proxy_msg_error(bcmolt_devid device, bcmolt_msg *proxy_msg)
{
    proxy_control_block *proxy = &proxy_data[device];
    ++proxy->stats.msg_errors;
    bcmolt_msg_err(proxy_msg, proxy->proxy_log, BCM_ERR_PARM, BCMOLT_ERR_FIELD_NONE, "Message is insane");
    proxy_msg->dir = BCMOLT_MSG_DIR_RESPONSE;
    return BCM_ERR_PARM;
}

static void _proxy_invoke(bcmolt_devid device, bcmolt_msg *proxy_msg)
{
    proxy_control_block *proxy = &proxy_data[device];
    bcmos_errno rc;
    bcmolt_system_mode system_mode;

    /* Check that the message targets an object that is compatible with our system mode */
    bcmolt_system_mode_get(device, &system_mode);
    if (system_mode != BCMOLT_SYSTEM_MODE__NUM_OF && !bcmolt_object_is_supported(system_mode, proxy_msg->obj_type))
    {
        ++proxy->stats.msg_errors;
        proxy_msg->dir = BCMOLT_MSG_DIR_RESPONSE;
        bcmolt_msg_err(
            proxy_msg,
            proxy->proxy_log,
            BCM_ERR_NOT_SUPPORTED,
            BCMOLT_ERR_FIELD_NONE,
            "Object type is not supported in this system mode");
        return;
    }

    /* Invoke API */
    switch (proxy_msg->group)
    {
        case BCMOLT_MGT_GROUP_CFG:
            if ((proxy_msg->type & BCMOLT_MSG_TYPE_CLEAR) != 0)
            {
                rc = bcmolt_cfg_clear(device, (bcmolt_cfg *)proxy_msg);
            }
            else if ((proxy_msg->type & BCMOLT_MSG_TYPE_GET) != 0)
            {
                if ((proxy_msg->type & BCMOLT_MSG_TYPE_MULTI) != 0)
                {
                    if (proxy_msg->msg_set == NULL)
                    {
                        rc = _proxy_msg_error(device, proxy_msg);
                    }
                    else
                    {
                        rc = bcmolt_cfg_get_multi(device,
                                                 (bcmolt_cfg *)proxy_msg,
                                                 proxy_msg->msg_set->filter_flags,
                                                 proxy_msg->msg_set);
                    }
                }
                else
                {
                    rc = bcmolt_cfg_get(device, (bcmolt_cfg *)proxy_msg);
                }
            }
            else if ((proxy_msg->type & BCMOLT_MSG_TYPE_SET) != 0)
            {
                rc = bcmolt_cfg_set(device, (bcmolt_cfg *)proxy_msg);
            }
            else
            {
                rc = _proxy_msg_error(device, proxy_msg);
            }
            break;

        case BCMOLT_MGT_GROUP_STAT:
            {
                bcmolt_stat_flags flags;

                flags = ((proxy_msg->type & BCMOLT_MSG_TYPE_CLEAR) != 0) ?
                        BCMOLT_STAT_FLAGS_CLEAR_ON_READ : 0;

                rc = bcmolt_stat_get(device, (bcmolt_stat *)proxy_msg, flags);
            }
            break;

        case BCMOLT_MGT_GROUP_OPER:
            rc = bcmolt_oper_submit(device, (bcmolt_oper *)proxy_msg);
            break;

        case BCMOLT_MGT_GROUP_PROXY:
            rc = bcmolt_proxy_send(device, (bcmolt_proxy *)proxy_msg);
            break;

        case BCMOLT_MGT_GROUP_STAT_CFG:
            if ((proxy_msg->type & BCMOLT_MSG_TYPE_GET) != 0)
            {
                rc = bcmolt_stat_cfg_get(device, (bcmolt_stat_cfg *)proxy_msg);
            }
            else if ((proxy_msg->type & BCMOLT_MSG_TYPE_SET) != 0)
            {
                rc = bcmolt_stat_cfg_set(device, (bcmolt_stat_cfg *)proxy_msg);
            }
            else
            {
                rc = _proxy_msg_error(device, proxy_msg);
            }
            break;

        case BCMOLT_MGT_GROUP_AUTO_CFG:
            if ((proxy_msg->type & BCMOLT_MSG_TYPE_GET) != 0)
            {
                rc = bcmolt_auto_cfg_get(device, (bcmolt_auto_cfg *)proxy_msg);
            }
            else if ((proxy_msg->type & BCMOLT_MSG_TYPE_SET) != 0)
            {
                rc = bcmolt_auto_cfg_set(device, (bcmolt_auto_cfg *)proxy_msg);
            }
            else
            {
                rc = _proxy_msg_error(device, proxy_msg);
            }
            break;

        default:
            rc = _proxy_msg_error(device, proxy_msg);
    }

    proxy_msg->err = rc;
}

/* Pack and send message */
static void _proxy_send(bcmolt_devid device, bcmolt_msg *msg)
{
    bcmtr_hdr hdr = {};
    int32_t packed_length;
    bcmolt_buf txb = {};
    int len;

    /* Allocate buffer and pack */
    packed_length = bcmolt_msg_get_packed_length(msg);
    if (packed_length <= 0)
    {
        ++proxy_data[device].stats.pack_errors;
        goto done;
    }
    packed_length += BCMTR_HDR_SIZE;
    if (bcmolt_buf_alloc(&txb, packed_length, BCMOLT_BUF_ENDIAN_FIXED) != BCM_ERR_OK)
    {
        ++proxy_data[device].stats.pack_errors;
        goto done;
    }
    bcmtr_header_fill(msg, &hdr);
    bcmtr_header_pack(&hdr, txb.start);
    bcmolt_buf_skip(&txb, BCMTR_HDR_SIZE);
    if (bcmolt_msg_pack(msg, &txb) != BCM_ERR_OK)
    {
        ++proxy_data[device].stats.pack_errors;
        goto done;
    }

    /* Send to client */
    len = sendto(proxy_data[device].client_socket, txb.start, bcmolt_buf_get_used(&txb), 0,
                 (struct sockaddr *)&proxy_data[device].client, sizeof(proxy_data[device].client));
    if (len <= 0)
    {
        ++proxy_data[device].stats.tx_errors;
    }
    else
    {
        ++proxy_data[device].stats.tx_packets;
        proxy_data[device].stats.tx_bytes += len;
    }

done:
    bcmolt_buf_free(&txb);
    return;
}

/* Task that waits for messages from Maple.
 * Once message is received, it is forwarded to remote application
 * via UDP socket.
 */
static int _proxy_rx_handler(long data)
{
    bcmolt_devid device = (bcmolt_devid)data;
    bcmos_task *self = bcmos_task_current();
    proxy_control_block *proxy = &proxy_data[device];
    struct sockaddr_in sender;
    socklen_t sendsize = sizeof(sender);
    uint8_t client_buffer[BCMTR_MAX_MTU_SIZE + 128];
    bcmolt_msg *proxy_msg;
    bcmtr_hdr tr_hdr;
    bcmolt_buf rxb;
    int len;
    uint16_t corr_tag;
    bcmos_errno rc;

    while (!self->destroyed)
    {
        memset(&sender, 0, sizeof(sender));
        len = recvfrom(proxy->client_socket, client_buffer, sizeof(client_buffer), 0,
                       (struct sockaddr *)&sender, &sendsize);
        if (len < BCMTR_HDR_SIZE)
        {
            ++proxy->stats.rx_errors;
            bcmos_usleep(1000000);
            continue;
        }
        ++proxy->stats.rx_packets;
        proxy->stats.rx_bytes += len;

        if (proxy->client.sin_addr.s_addr != sender.sin_addr.s_addr ||
            proxy->client.sin_port != sender.sin_port)
        {
#ifdef ENABLE_LOG
            int client_ip = ntohl(sender.sin_addr.s_addr);
            int client_port = ntohs(sender.sin_port);
            BCM_LOG(INFO, proxy->proxy_log, "bcm_api_proxy: device %i connected to %d.%d.%d.%d:%d\n",
                    (int)device,
                    (client_ip >> 24) & 0xff, (client_ip >> 16) & 0xff,
                    (client_ip >> 8) & 0xff, client_ip & 0xff, client_port);
#endif
            proxy->client = sender;
        }

        /* Unpack received message */
        bcmolt_buf_init(&rxb, len, client_buffer, BCMOLT_BUF_ENDIAN_FIXED);
        bcmtr_header_unpack(client_buffer, &tr_hdr);

        /* Skip registration messages for now. The proxy has already registered for everything */
        if (tr_hdr.auto_proxy_reg || tr_hdr.auto_proxy_unreg)
            continue;

        bcmolt_buf_skip(&rxb, BCMTR_HDR_SIZE);
        proxy_msg = NULL;
        rc = bcmolt_msg_unpack(&rxb, &proxy_msg);
        if (rc)
        {
            /* Unpack error. Nothing much we can do */
            ++proxy->stats.unpack_errors;
            continue;
        }

        /* Store correlation tag for later */
        proxy_msg->corr_tag = tr_hdr.corr_tag;
        corr_tag = proxy_msg->corr_tag;

        /* Point the message unpacker to local storage for dynamically-sized lists */
        proxy_msg->list_buf = proxy->dynamic_list_buffer;
        proxy_msg->list_buf_size = DYNAMIC_LIST_BUFFER_SIZE;

        /* Invoke API */
        _proxy_invoke(device, proxy_msg);

        /* Pack and send back to the client */
        proxy_msg->corr_tag = corr_tag;
        _proxy_send(device, proxy_msg);
        bcmolt_msg_free(proxy_msg);
    }

    self->destroyed = BCMOS_TRUE;
    return 0;
}

/* Auto / proxy message handler */
void bcmolt_api_proxy_auto_rx_cb(bcmolt_devid device, bcmolt_msg *msg)
{
    if (device >= BCMTR_MAX_OLTS)
        return;

    if (proxy_data[device].is_running)
    {
        if (proxy_data[device].on_ready_cmd &&
            msg->obj_type == BCMOLT_OBJ_ID_DEVICE &&
            msg->group == BCMOLT_MGT_GROUP_AUTO &&
            msg->subgroup == BCMOLT_DEVICE_AUTO_ID_CONNECTION_COMPLETE)
        {
            char on_ready_cmd[512];
            int rc;
            snprintf(on_ready_cmd, sizeof(on_ready_cmd) - 1, "%s %d", proxy_data[device].on_ready_cmd, (int)device);
            rc = system(on_ready_cmd);
#ifdef ENABLE_LOG
            BCM_LOG(INFO, proxy_data[device].proxy_log, "Executed command %s. rc=%d\n", on_ready_cmd, rc);
#else
            (void)rc;
#endif
        }
        _proxy_send(device, msg);
    }
}

static bcmos_errno _proxy_start(bcmolt_devid device, uint32_t udp_port, char *on_ready)
{
    bcmos_errno rc;
    bcmos_task_parm proxy_rx_parm =
    {
        .name = "proxy_rx",
        .handler = _proxy_rx_handler,
        .priority = TASK_PRIORITY_TRANSPORT_PROXY,
        .data = device
    };
    struct sockaddr_in sa = {};

    proxy_data[device].proxy_port = udp_port;
    proxy_data[device].device_id = device;
    proxy_data[device].on_ready_cmd = on_ready;

    /* Start listening on proxy port */
    proxy_data[device].client_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (proxy_data[device].client_socket < 0)
    {
#ifdef ENABLE_LOG
        BCM_LOG(ERROR, proxy_data[device].proxy_log, "Can't create UDP socket\n");
#endif
        return BCM_ERR_INTERNAL;
    }

    /* Bind local */
    sa.sin_family = AF_INET;
    sa.sin_port = htons(proxy_data[device].proxy_port);
    sa.sin_addr.s_addr = INADDR_ANY;
    if (bind(proxy_data[device].client_socket, (struct sockaddr*)&sa, sizeof(sa) ) == -1)
    {
        perror("bind");
#ifdef ENABLE_LOG
        BCM_LOG(ERROR, proxy_data[device].proxy_log, "Can't bind UDP socket to port %u\n", proxy_data[device].proxy_port);
#endif
        close(proxy_data[device].client_socket);
        return BCM_ERR_INTERNAL;
    }

    /* Create thread listening for incoming APIs */
    rc = bcmos_task_create(&proxy_data[device].proxy_rx_task, &proxy_rx_parm);
    BUG_ON(BCM_ERR_OK != rc);

    proxy_data[device].is_running = BCMOS_TRUE;

#ifdef ENABLE_LOG
    BCM_LOG(INFO, proxy_data[device].proxy_log, "BCM68620 API proxy for device %d is listening for requests on UDP port %u\n",
        (int)device, proxy_data[device].proxy_port);
#endif

    return BCM_ERR_OK;
}

bcmos_errno bcmolt_api_proxy_init(bcmcli_entry *root, bcmolt_devid device, uint32_t udp_port, char *on_ready)
{
#ifdef ENABLE_CLI
    bcmcli_entry *dir;
#endif

    if (device >= BCMTR_MAX_OLTS)
        return BCM_ERR_PARM;

    if (proxy_data[device].is_running)
        return BCM_ERR_ALREADY;

#ifdef ENABLE_LOG
    {
        char log_id[32];
        snprintf(log_id, sizeof(log_id) - 1, "proxy_%d", (int)device);
        proxy_data[device].proxy_log = bcm_dev_log_id_register(log_id, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    }
#else
    proxy_data[device].proxy_log = DEV_LOG_INVALID_ID;
#endif

    if (is_first_proxy)
    {
#ifdef ENABLE_CLI
        dir = bcmcli_dir_add(root, "proxy", "API proxy", BCMCLI_ACCESS_GUEST, NULL);
        if (!dir)
        {
            BCM_LOG(ERROR, proxy_data[device].proxy_log, "Can't create proxy directory\n");
            BUG();
        }

        BCMCLI_MAKE_CMD(dir, "stat", "Proxy statistics", _proxy_stats_cmd,
            BCMCLI_MAKE_PARM_RANGE("device", "Device index", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_OPTIONAL,
                0, BCMTR_MAX_OLTS-1));

#endif
        is_first_proxy = BCMOS_FALSE;
    }
    return _proxy_start(device, udp_port, on_ready);
}

void bcmolt_api_proxy_stop(void)
{
    int i;

    for (i = 0; i < BCMTR_MAX_OLTS; i++)
    {
        if (proxy_data[i].is_running)
        {
            bcmos_task_destroy(&proxy_data[i].proxy_rx_task);
            close(proxy_data[i].client_socket);
        }
    }
}

