//
// Created by Administrator on 2025/12/24.
//

#include <rtthread.h>
#include <rtdevice.h>

// eRPC setup

#include "erpc_server_setup.h"
#include "erpc_transport_setup.h"
#include "erpc_mbf_setup.h"
#include "erpc_usb_cdc_transport.hpp"


#include "erpc/proto/generated/servo_service_server.hpp"
#include "erpc/proto/generated/servo_service_interface.hpp"
#include "erpc/service/include/servo_service_impl.h"
#include "erpc/common/include/erpc_error_handler.h"


#include "erpc/proto/generated/file_service_server.hpp"
#include "erpc/proto/generated/file_service_interface.hpp"
#include "erpc/service/include/file_service_impl.h"



#ifndef ERPC_THREAD_STACK
#define ERPC_THREAD_STACK (4096)
#endif

#ifndef ERPC_THREAD_PRIO
#define ERPC_THREAD_PRIO  (4)
#endif

#ifndef ERPC_THREAD_TICK
#define ERPC_THREAD_TICK  (5)
#endif

static void erpc_server_entry(void *parameter)
{
    (void)parameter;
    // 1) transport
    static serial_port_usb_cdc_config_t cfg = {
        .dev_name = "cdc0",
        .rx_wait_ms = -1,
        .tx_wait_ms = 2000,
    };

    erpc_transport_t transport = erpc_transport_usb_cdc_init(NULL, NULL, &cfg, NULL, 0);
    // erpc_transport_t transport = erpc_transport_serial_init(ERPC_SERVER_UART_NAME,ERPC_UART_BAUD);
    // erpc_transport_t transport = erpc_transport_cmsis_uart_init(ERPC_SERVER_UART_NAME);
    if (!transport)
    {
        rt_kprintf("[erpc] transport init failed!\r\n");
        return;
    }

    // 2) message buffer factory
    erpc_mbf_t mbf = erpc_mbf_dynamic_init();
    if (!mbf)
    {
        rt_kprintf("[erpc] mbf init failed!\r\n");
        return;
    }

    // 3) init server（注意：返回 server 句柄）
    erpc_server_t server = erpc_server_init(transport, mbf);
    if (!server)
    {
        rt_kprintf("[erpc] server init failed!\r\n");
        return;
    }

    // 4) register service
    static ServoServiceImpl impl;          // 必须继承 erpcShim::demo_interface
    static erpcShim::servo_service_service service(&impl);   // 生成的 service wrapper

    erpc_add_service_to_server(server, &service);

    static FileServiceImpl file_impl;
    static erpcShim::file_service_service file_service(&file_impl);
    erpc_add_service_to_server(server, &file_service);


    rt_kprintf("[erpc] server run\r\n");
    erpc_server_run(server);
    while (true){
        erpc_status_t tcp_status = erpc_server_poll(server);
        if (tcp_status != kErpcStatus_Success)
        {
            erpc_error_handler(tcp_status,0);
        }
    }
}

extern "C" int erpc_server_start(void)
{
    rt_thread_t tid = rt_thread_create("erpc_srv",
                                       erpc_server_entry,
                                       RT_NULL,
                                       ERPC_THREAD_STACK,
                                       ERPC_THREAD_PRIO,
                                       ERPC_THREAD_TICK);
    if (!tid)
    {
        rt_kprintf("[erpc] create thread failed!\r\n");
        return -RT_ERROR;
    }

    rt_thread_startup(tid);
    return RT_EOK;
}


INIT_APP_EXPORT(erpc_server_start);
