/****************HEADER FILE******************/
#include <stdlib.h>
#include <string.h>

#include "dy_utils/cJSON.h"
#include "dy_utils/dy_common.h"
#include "rs485_slave_common.h"
/**********************************************/

/******************INTERN MACRO*****************/
#define RS485_SLAVE_PORT_CFG "/app/config/rs485_slave_port_cfg.json"
/**************************************************/

/**************INTERN FUNCTION DECLERATION**********/
static int rs485_slave_port_cfg_parse(rs485_slave_ports_cfg_t *cfgs, const char *str);
/**************************************************/

/****************EXTERN FUNCTION******************/
void rs485_slave_load_config(rs485_slave_var_t *var)
{
    char *json_str = read_file_data(RS485_SLAVE_PORT_CFG);
    if (json_str)
    {
        rs485_slave_port_cfg_parse(&var->rs485_slave_ports_cfg, json_str);
        free(json_str);
    }
}
/**************************************************/

/****************INTERN FUNCTION******************/
static int rs485_slave_port_cfg_parse(rs485_slave_ports_cfg_t *cfgs, const char *str)
{
    char buff[128] = {0};
    int ret = -1;
    int i = 0;
    int size = 0;
    rs485_slave_port_cfg_t *cfg = NULL;
    cJSON *root = NULL;
    cJSON *nodes = NULL;
    cJSON *node = NULL;

    if (!str || !cfgs)
    {
        return -1;
    }

    root = cJSON_Parse(str);
    if (!root)
    {
        return -1;
    }

    GET_JSON_VALUE_INT(root, "mi", cfgs->mi);
    nodes = cJSON_GetObjectItem(root, "rs485_slave_cfg");
    if (!nodes)
    {
        ret = -1;
        goto cleanup;
    }

    size = cJSON_GetArraySize(nodes);
    ASSERT(size <= TTYMXC_CNT);

    for (i = 0; i < size ; i++)
    {
        node = cJSON_GetArrayItem(nodes, i);
        if (!node)
        {
            ret = -1;
            goto cleanup;
        }
        cfg = &cfgs->rs485_slave_port_cfg[i];
        GET_JSON_VALUE_STRING(node, "port", buff);
        if (strlen(buff) > 0)
        {
            cfg->port = port_char2enum(buff);
        }
        else
        {
            cfg->port = 0;
        }
        GET_JSON_VALUE_STRING(node, "protocol", buff);
        if (strlen(buff) > 0)
        {
            cfg->protocol = protocol_char2enum(buff);
        }
        else
        {
            cfg->protocol = 0;
        }

        GET_JSON_VALUE_INT(node, "speed", cfg->speed);
        GET_JSON_VALUE_INT(node, "stop", cfg->stop);
        GET_JSON_VALUE_INT(node, "parity", cfg->parity);
        GET_JSON_VALUE_INT(node, "bits", cfg->bits);
        GET_JSON_VALUE_INT(node, "disable", cfg->disable);
        dy_syslog(LOG_INFO, "cnt %d %d port %d speed %d bits %d stop %d parity %d protocol %d disable %d\n", size, i, cfg->port, cfg->speed, cfg->bits, cfg->stop, cfg->parity, cfg->protocol, cfg->disable);
    }

    ret = 0;

cleanup:
    cJSON_Delete(root);
    return ret;
}

const char *get_tty_from_port(gw_port_e port)
{
    const char *board_name = get_board_name();

    if (strcmp(board_name, BOARD_WOOLINK_MT7628) == 0)
    {
        switch (port)
        {
        case RS485_1:
            return "/dev/ttyS1";
            break;
        case RS485_2:
        case RS232_1:
            return "/dev/ttyS0";
            break;
        default:
            break;
        }
    }
    else if (strcmp(board_name, BOARD_WOOLINK_MT7621) == 0)
    {
        switch (port)
        {
        case RS485_1:
            return "/dev/ttyFTDI0";
            break;
        case RS485_2:
            return "/dev/ttyFTDI1";
            break;
        case RS485_3:
            return "/dev/ttyFTDI2";
            break;
        case RS485_4:
            return "/dev/ttyFTDI3";
            break;
        default:
            break;
        }
    }
    else
    {
        switch (port)
        {
        case RS485_1:
            return "/dev/ttymxc1";
            break;
        case RS485_2:
            return "/dev/ttymxc2";
            break;
        case RS485_3:
            return "/dev/ttymxc3";
            break;
        case RS485_4:
            return "/dev/ttymxc4";
            break;
        default:
            break;
        }
    }

    return NULL;
}

int rs485_slave_port_map(int rs485_slave_port)
{
    int port = 0;

    switch (rs485_slave_port)
    {
    case RS485_1:
        port = 0;
        break;
    case RS485_2:
        port = 1;
        break;
    case RS485_3:
        port = 2;
        break;
    case RS485_4:
        port = 3;
        break;
    }

    return port;
}
/**************************************************/
