#include "shell/sh.h"
#include "sh_vset.h"

#include "config/board_config.h"
#include "config/app_config.h"
#include "config/version.h"

#define CONFIG_SYS_LOG_LEVEL SYS_LOG_LEVEL_DBG
#define SYS_LOG_DOMAIN "FW-INFO"
#include "sys_log.h"

#define _YEAR ((((__DATE__[7] - '0') * 10 + (__DATE__[8] - '0')) * 10 + (__DATE__[9] - '0')) * 10 + (__DATE__[10] - '0'))

#define _MONTH ((__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')   ? 1  \
                : (__DATE__[0] == 'F' && __DATE__[1] == 'e' && __DATE__[2] == 'b') ? 2  \
                : (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r') ? 3  \
                : (__DATE__[0] == 'A' && __DATE__[1] == 'p' && __DATE__[2] == 'r') ? 4  \
                : (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y') ? 5  \
                : (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n') ? 6  \
                : (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l') ? 7  \
                : (__DATE__[0] == 'A' && __DATE__[1] == 'u' && __DATE__[2] == 'g') ? 8  \
                : (__DATE__[0] == 'S' && __DATE__[1] == 'e' && __DATE__[2] == 'p') ? 9  \
                : (__DATE__[0] == 'O' && __DATE__[1] == 'c' && __DATE__[2] == 't') ? 10 \
                : (__DATE__[0] == 'N' && __DATE__[1] == 'o' && __DATE__[2] == 'v') ? 11 \
                                                                                   : 12)

#define _DAY ((__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 + (__DATE__[5] - '0'))

SH_CMD_FN(_log1);
SH_CMD_FN(_log0);
SH_CMD_FN(_fw_info);
SH_CMD_FN(_licenseCode);
SH_CMD_FN(_boardcfgDump);
SH_CMD_FN(_boardcfgSave);

SH_DEF_CMD(
    _register_cmd_hide,
    SH_SETUP_CMD("syslogON", "Enable sys log", _log1, NULL),                                     //
    SH_SETUP_CMD("info", "Firmware information", _fw_info, NULL),                                //
    SH_SETUP_CMD("licenseCode", "Set up new license code <code[16]>", _licenseCode, NULL),       //
    SH_SETUP_CMD("boardcfgDump", "Dump complete board configuration data", _boardcfgDump, NULL), //
    SH_SETUP_CMD("boardcfgSave", "Store board configuration code", _boardcfgSave, NULL),         //
);

SH_DEF_CMD(
    _register_cmd,
    SH_SETUP_CMD("log-off", "Disable sys log", _log0, NULL), //
);

void app_info_register(void)
{
    sh_register_cmd_hide(&_register_cmd_hide);
    sh_register_cmd(&_register_cmd);
}

SH_CMD_FN(_log1)
{
    sh_hdl->disable_echo = false;
    app_cfg_set_sys_log(true);
    return 0;
}

SH_CMD_FN(_log0)
{
    app_cfg_set_sys_log(false);
    return 0;
}

SH_CMD_FN(_fw_info)
{
    static char *const rf_tab[] = {
        [DATA_BRIDGE_RF_MODE_OFF] = "off",           // 设置数据桥接模式：关闭所有数据接口
        [DATA_BRIDGE_RF_MODE_BLE] = "ble",           // 设置数据桥接模式：仅使用 UART <==> BLE
        [DATA_BRIDGE_RF_MODE_WIFI_AP] = "wifi-ap",   // 设置数据桥接模式：仅使用 UART <==> WIFI(AP)
        [DATA_BRIDGE_RF_MODE_WIFI_STA] = "wifi-sta", // 设置数据桥接模式：仅使用 UART <==> WIFI(STA)
    };
    char mac_buf[3];
    memset(mac_buf, 0, sizeof(mac_buf));

    printf("\r\n--------======== Firmware information ========--------\r\n");
    printf("build time     %04d-%02d-%02d %s\r\n", _YEAR, _MONTH, _DAY, __TIME__);
    printf("release code   " FW_RELEASE_CODE "\r\n");
    printf("board name     %s\r\n", g_cfg_board->board_name);
    printf("firmware type  %s\r\n", g_cfg_board->firmware_str);
    printf("firmware ver   %u.%u.%u\r\n", FW_VERSION_MAIN, FW_VERSION_MINOR, FW_VERSION_BUILD);
    printf("platform       %s\r\n", g_cfg_board->platform_str);
    printf("ble name       %s\r\n", g_cfg_app->device_name_ble);
    printf("ble pawd       %s\r\n", g_cfg_app->psPassword);
#if (CONFIG_BUILD_WIFI)
    printf("wifi ap ssid   %s\r\n", g_cfg_app->app_config_wifi_para.wifi_ap_ssid);
    printf("wifi ap pawd   %s\r\n", g_cfg_app->app_config_wifi_para.wifi_ap_password);
    printf("wifi sta ssid  %s\r\n", g_cfg_app->app_config_wifi_para.wifi_sta_ssid);
    printf("wifi sta pawd  %s\r\n", g_cfg_app->app_config_wifi_para.wifi_sta_password);
#endif
    printf("rf mode        %s\r\n", rf_tab[g_cfg_app->rf_mode]);
    printf("mac            ");
    for (int i = 0; i < 6; i++)
    {
        memcpy(mac_buf, &g_cfg_app->dev_mac_str[i * 2], 2);
        printf("%s%s", mac_buf, i < 5 ? ":" : "\r\n");
    }
    printf("license code   ");
    for (int i = 0; i < CONFIG_LICENSE_CODE_LENGTH; i++)
    {
        printf("%02X", g_license_code[i]);
    }
    printf("\r\n");
    printf("END ------------\r\n");
    return 0;
}

SH_CMD_FN(_licenseCode)
{
    const uint8_t code_str_len = CONFIG_LICENSE_CODE_LENGTH * 2;
    uint8_t license_code[CONFIG_LICENSE_CODE_LENGTH];

    if (argc < 1)
    {
        printf("缺少参数 <code[%u]>\r\n", code_str_len);
        return -1;
    }

    sh_parse_t pv = sh_parse_value(argv[0]);
    switch (pv.type)
    {
    case _PARSE_TYPE_STRING: // 字符串
    {
        if (strlen(pv.value.val_string) != code_str_len)
        {
            printf("代码字符串长度为 %u 个字节，当前共 %u 字节\r\n", code_str_len, strlen(pv.value.val_string));
            return -1;
        }
        break;
    }
    case _PARSE_TYPE_INTEGER:  // 带符号整型
    case _PARSE_TYPE_UNSIGNED: // 无符号整型
    case _PARSE_TYPE_FLOAT:    // 浮点
    default:
        printf("<code[%u]> 只支持字符串的十六进制格式表示\r\n", code_str_len);
        return -1;
    }

    char code_str[5] = "0x00";
    for (int i = 0; i < CONFIG_LICENSE_CODE_LENGTH; i++)
    {
        strncpy(&code_str[2], &argv[0][i * 2], 2);
        pv = sh_parse_value(code_str);
        if (pv.type != _PARSE_TYPE_UNSIGNED)
        {
            printf("十六进制字符串格式错误:\r\n%s\r\n", argv[0]);
            for (int j = 0; j < i; j++)
            {
                printf("  ");
            }
            printf("^~\r\n");
            return -1;
        }
        license_code[i] = pv.value.val_unsigned;
    }

    if (board_license_fresh(license_code) == 0)
    {
        _fw_info(sh_hdl, 0, NULL);
        return 0;
    }
    else
    {
        return -1;
    }
}

SH_CMD_FN(_boardcfgDump)
{
    return board_cfg_dump(g_cfg_board);
}

SH_CMD_FN(_boardcfgSave)
{
    return board_cfg_fresh(g_cfg_board);
}
