#include "ble_spp_client_shell.h"
#include "ble_spp_client.h"
#include "shell/sh.h"

#include <string.h>

#include "drivers/data_port/sb_data_port.h"

static sh_cp_param_t const s_param_profile[] = {
    {"\"SpeedyBee F405 Mini\"", "SpeedyBee F405 Mini"},
    {NULL},
};

static void _ble_connect_cb(ble_client_status_t status);

SH_CMD_FN(_start);
SH_CMD_FN(_stop);
SH_CMD_FN(_status);
SH_CMD_FN(_write);

SH_CMD_CP_FN(_start_cp);

SH_DEF_SUB_CMD(
    sub_ble,
    SH_SETUP_CMD("start", "开始扫描指定的设备名并连接 <设备名>", _start, _start_cp), //
    SH_SETUP_CMD("stop", "停止扫描，断开连接", _stop, NULL),                         //
    SH_SETUP_CMD("status", "获取当前连接状态", _status, NULL),                       //
    SH_SETUP_CMD("write", "发送数据 <数值|字符串>", _write, NULL),                   //
);

SH_DEF_CMD(
    _register_cmd_ble,
    SH_SETUP_CMD("ble", "操作 BLE 透传数据接口", NULL, sub_ble), //
);

void ble_client_shell_register(void)
{
    sh_register_cmd(&_register_cmd_ble);
}

void ble_client_shell_unregister(void)
{
    sh_unregister_cmd(&_register_cmd_ble);
}

static void _ble_connect_cb(ble_client_status_t status)
{
    sh_echo(&g_uart_handle_vt100, "\r\n");
    _status(&g_uart_handle_vt100, 0, NULL);
}

SH_CMD_FN(_start)
{
    if (argc < 1)
    {
        sh_echo(sh_hdl, "缺少参数\r\n");
        return -1;
    }

    if (argc > 1)
    {
        sh_echo(sh_hdl, "参数中有空格。如果目标设备名中包含空格，请使用引号表示\r\n");
        return -1;
    }

    ble_client_start(argv[0], _ble_connect_cb);
    return 0;
}

SH_CMD_FN(_stop)
{
    ble_client_stop();
    os_thread_sleep(100);
    return 0;
}

SH_CMD_FN(_status)
{
    static char *const str[] = {
        [BLE_CLIENT_STATUS_STOP] = "stop",
        [BLE_CLIENT_STATUS_SCANNING] = "scanning",
        [BLE_CLIENT_STATUS_CONNECTED] = "connected",
        [BLE_CLIENT_STATUS_DISCONNECTED] = "disconnected",
    };
    ble_client_status_t status = ble_client_get_gap_status();
    if (status < sizeof(str) / sizeof(str[0]) && str[status] != NULL)
    {
        sh_echo(sh_hdl, "connect status: %s\r\n", str[status]);
    }
    else
    {
        sh_echo(sh_hdl, "unknow status: %d\r\n", status);
    }
    return 0;
}

SH_CMD_FN(_write)
{
    int ret = -1;
    if (argc < 1)
    {
        sh_echo(sh_hdl, "缺少参数\r\n");
        return -1;
    }

    sh_parse_t pv = sh_parse_value(argv[0]);
    switch (pv.type)
    {
    case _PARSE_TYPE_STRING: // 字符串
        ret = sb_data_port_write(ble_client_port_bind(), pv.value.val_string, strlen(pv.value.val_string), 0);
        break;
    case _PARSE_TYPE_INTEGER: // 带符号整型
        ret = sb_data_port_write(ble_client_port_bind(), &pv.value.val_integer, sizeof(pv.value.val_integer), 0);
        break;
    case _PARSE_TYPE_UNSIGNED: // 无符号整型
        ret = sb_data_port_write(ble_client_port_bind(), &pv.value.val_unsigned, sizeof(pv.value.val_unsigned), 0);
        break;
    case _PARSE_TYPE_FLOAT: // 浮点
        ret = sb_data_port_write(ble_client_port_bind(), &pv.value.val_float, sizeof(pv.value.val_float), 0);
        break;

    default:
        return -1;
    }

    os_thread_sleep(50);
    return ret;
}

SH_CMD_CP_FN(_start_cp)
{
    if (argc + flag == 1)
    {
        sh_completion_param(sh_hdl, s_param_profile);
    }
}
