/**
 * @file    com_router_dispatch.cpp
 * @brief   通信路由分发 — 通道转发 + FTU串口接收分路 (MQ 模式)
 */

#include "mySystem.h"
#include "myComm.h"
#include "myLog.h"
#include "myIcp67.h"
#include "com_router.h"

#include <string.h>

/* =========================== 前向声明 =========================== */

/* 来自 com_router.cpp 的内部函数 */
extern com_router_dispatch_cb com_router_dispatch_find(const char *bind_app);

/* =========================== 全局变量引用 =========================== */

extern com_channel_t        g_channels[];
extern int                  g_channel_count;
extern com_forward_rule_t   g_forward_rules[];
extern int                  g_forward_count;

/* =========================== MQ 投递辅助 =========================== */

/**
 * @brief 通过 MQ_COM_TO_SELF_PTL 将数据投递给 self_ptl
 *
 * @details 封装 MQ 发送 + 事件通知:
 *          1. task_msg_queue_send(MQ_COM_TO_SELF_PTL)
 *          2. task_event_send(EV_SELF_PTL_RX_COM) → 唤醒 self_ptl 线程
 */
static int com_router_send_to_self_ptl(uint32_t interface,
	const unsigned char *p_data, int data_len)
{
	stru_app_msg_queue *p_mq;
	stru_app            *p_app;
	stru_mq_target       target;

	p_mq = app_get_msg_queue_ptr(ENUM_MQ_COM_TO_SELF_PTL);
	if(NULL == p_mq || NULL == p_mq->p_msg_queue)
	{
		LOG_E("com_router: MQ_COM_TO_SELF_PTL not found");
		return -1;
	}

	/* 封装 stru_msg_head → MQ */
	{
		stru_app *p_self = app_get_ptr(ENUM_APP_COM_ROUTER);
		stru_msg_head *p_head;

		if(NULL == p_self)
		{
			return -1;
		}

		p_head = (stru_msg_head *)p_self->rtx.tx;
		p_head->interface = interface;
		p_head->len = (uint16_t)data_len;
		memcpy(p_head->data, p_data, data_len);

		task_msg_queue_send(p_mq->p_msg_queue, p_head, p_mq->msg_size);
	}

	/* 通知 self_ptl 线程 */
	target = app_get_mq_target(ENUM_MQ_COM_TO_SELF_PTL);
	p_app  = app_get_ptr(target.app_id);
	if(NULL != p_app && NULL != p_app->p_event)
	{
		task_event_send(p_app->p_event, target.event);
	}

	return 0;
}

/* =========================== 内部辅助 =========================== */

static com_forward_rule_t *com_router_fwd_find_by_fd(int sock_fd)
{
	int i;

	for(i = 0; i < g_forward_count; i++)
	{
		if(g_forward_rules[i].sock_fd == sock_fd)
		{
			return &g_forward_rules[i];
		}
	}

	return NULL;
}

static com_forward_rule_t *com_router_fwd_find_by_target(int ch_id)
{
	int i;

	for(i = 0; i < g_forward_count; i++)
	{
		if(g_forward_rules[i].target_ch_id == ch_id
			&& g_forward_rules[i].sock_fd >= 0)
		{
			return &g_forward_rules[i];
		}
	}

	return NULL;
}

static int com_router_fwd_send_back(int serial_ch_id,
	const unsigned char *p_data, int data_len)
{
	com_forward_rule_t *fw = com_router_fwd_find_by_target(serial_ch_id);

	if(NULL == fw)
	{
		return -1;
	}

	comm_send(serial_ch_id, fw->sock_fd, p_data, data_len);
	return 0;
}

/* =========================== 核心: 数据接收回调 =========================== */

/*
 * 路由优先级:
 *   1. 匹配 forward_rule.sock_fd  → 透传到目标通道 (维护透传)
 *   2. 通道 bind_app 非空         → 整帧投递给注册的协议模块回调
 *   3. bind_app 为空 (FTU 串口)   → 按帧内容分路 (ICP67/IEC 帧识别)
 */

void com_router_recv_cb(int id, int fd, const unsigned char *p_rx, int rx_len)
{
	com_channel_t *ch = NULL;
	int i;

	if(NULL == p_rx || 0 == rx_len)
	{
		return;
	}

	/* Step 1: 转发通道 → FTU 串口透传 */
	{
		com_forward_rule_t *fw = com_router_fwd_find_by_fd(fd);

		if(NULL != fw && fw->target_ch_id >= 0)
		{
			comm_send(fw->target_ch_id, 0, p_rx, rx_len);
			return;
		}
	}

	/* 查找通道配置 */
	for(i = 0; i < g_channel_count; i++)
	{
		if(g_channels[i].id == id)
		{
			ch = &g_channels[i];
			break;
		}
	}

	if(NULL == ch)
	{
		return;
	}

	/* Step 2: bind_app 协议绑定 → 直接投递给注册的协议模块 */
	if('\0' != ch->bind_app[0])
	{
		com_router_dispatch_cb dispatch = com_router_dispatch_find(ch->bind_app);

		if(NULL != dispatch)
		{
			uint32_t interface = ((uint32_t)id << 16) | (uint32_t)fd;

			dispatch(interface, p_rx, rx_len);
			return;
		}

		LOG_E("com_router: bind_app [%s] has no dispatch registered", ch->bind_app);
		return;
	}

	/* Step 3: bind_app 为空 → FTU 串口按帧内容分路 */

	/* a) ICP67 维护软件回复 (dev_addr=0) */
	if(rx_len >= (int)sizeof(stru_head)
		&& 0x67 == p_rx[0] && 0x67 == p_rx[3]
		&& DEV_MAINTENANCE_ADDR == ((stru_head *)p_rx)->dev_addr)
	{
		com_router_fwd_send_back(id, p_rx, rx_len);
		return;
	}

	/* b) IEC-104 帧 → 回传转发通道 */
	if(rx_len >= 1 && (0x68 == p_rx[0] || 0x10 == p_rx[0]))
	{
		com_router_fwd_send_back(id, p_rx, rx_len);
		return;
	}

	/* c) ICP67 帧 (dev_addr != 维护地址) → MQ_COM_TO_SELF_PTL → self_ptl */
	if(rx_len >= (int)sizeof(stru_head)
		&& 0x67 == p_rx[0] && 0x67 == p_rx[3]
		&& DEV_MAINTENANCE_ADDR != ((stru_head *)p_rx)->dev_addr)
	{
		uint32_t interface = ((uint32_t)id << 16) | (uint32_t)fd;

		com_router_send_to_self_ptl(interface, p_rx, rx_len);
		return;
	}

	LOG_E("com_router_recv_cb: unhandled, ch=%s, len=%d, head=0x%02X",
		ch->key, rx_len, p_rx[0]);
}
