#include "app.hpp"
#include <cassert>
#include <iostream>
#include <vector>
#include <cmath>

/**
 * @brief 测试基础通用通信单元 (SU-COM) 的接口初始化功能。
 *
 * @requirement(name="基础通用通讯功能", id="SRS-F-01-001")
 * 验证以太网、RS422、CAN、模拟量、离散量接口初始化正确性。
 */
static void test_su_com_communication() {
    std::cout << "[TEST] SU-COM: 基础通用通信测试...\n";

    // 以太网：有效参数应返回 true
    assert(bntvs::initEthernetComm("192.168.1.1", 8080) == true);
    // 空 IP 应返回 false
    assert(bntvs::initEthernetComm("", 8080) == false);

    // RS422：有效参数应返回 true
    assert(bntvs::initRS422Comm("COM1", 115200) == true);
    // 波特率过低应返回 false
    assert(bntvs::initRS422Comm("COM1", 100) == false);

    // CAN：有效参数应返回 true
    assert(bntvs::initCANComm("can0", 250000) == true);
    // 波特率超范围应返回 false
    assert(bntvs::initCANComm("can0", 2000000) == false);

    // 模拟量：应返回 true
    assert(bntvs::initAnalogComm(0) == true);

    // 离散量：有效引脚应返回 true
    assert(bntvs::initDigitalComm(0) == true);
    // 引脚超范围应返回 false
    assert(bntvs::initDigitalComm(48) == false);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试协议兼容单元 (SU-PROT) 的协议识别与转换功能。
 *
 * @requirement(name="协议兼容功能", id="SRS-F-01-002")
 * 验证 CAN2.0 与 CAN FD 协议的自动识别和兼容转换。
 */
static void test_su_prot_protocol_compat() {
    std::cout << "[TEST] SU-PROT: 协议兼容测试...\n";

    // CAN2.0 帧（≤8 字节）
    std::vector<uint8_t> can20_data = {0x11, 0x22, 0x33, 0x44};
    assert(bntvs::detectCANProtocol(can20_data) == bntvs::CANProtocolType::CAN2_0);

    // CAN FD 帧（>8 字节）
    std::vector<uint8_t> canfd_data(32, 0x55);
    assert(bntvs::detectCANProtocol(canfd_data) == bntvs::CANProtocolType::CANFD);

    // CAN FD → CAN 2.0 转换
    auto result = bntvs::convertCANFrame(
        bntvs::CANProtocolType::CANFD,
        bntvs::CANProtocolType::CAN2_0,
        canfd_data);
    assert(result.size() == 8);  // 截断到 8 字节

    // CAN 2.0 → CAN FD 转换（相同协议不应改变）
    result = bntvs::convertCANFrame(
        bntvs::CANProtocolType::CAN2_0,
        bntvs::CANProtocolType::CAN2_0,
        can20_data);
    assert(result.size() == can20_data.size());

    std::cout << "  PASS\n";
}

/**
 * @brief 测试数据存储单元 (SU-STOR) 的功能。
 *
 * @requirement(name="数据存储功能", id="SRS-F-02-001")
 * 验证数据持久化存储及存储服务生命周期管理。
 */
static void test_su_stor_data_storage() {
    std::cout << "[TEST] SU-STOR: 数据存储测试...\n";

    // 存储服务未启动时，存储应失败
    bntvs::BusDataRecord record;
    record.bus_type = "CAN";
    record.frame_id = 0x100;
    record.data_content = {0x01, 0x02};
    record.data_length = 2;
    assert(bntvs::storeBusData(record) == false);

    // 启动存储服务后，存储应成功
    assert(bntvs::startStorageService() == true);
    assert(bntvs::storeBusData(record) == true);

    // 重复启动不应失败
    assert(bntvs::startStorageService() == true);

    // 停止存储服务
    assert(bntvs::stopStorageService() == true);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试数据管理与回放单元 (SU-REPLAY) 的功能。
 *
 * @requirement(name="数据管理与数据回放功能", id="SRS-F-02-002")
 * 验证数据查询、回放和删除功能。
 */
static void test_su_replay_data_management() {
    std::cout << "[TEST] SU-REPLAY: 数据管理与回放测试...\n";

    // 查询（返回空列表）
    auto results = bntvs::queryBusData("CAN", "2024-01-01", "2024-12-31");
    assert(results.empty());

    // 回放
    bntvs::BusDataRecord record;
    uint64_t callback_count = 0;
    uint64_t replayed = bntvs::replayBusData(
        {record, record, record}, 2.0,
        [&callback_count](const bntvs::BusDataRecord&) { ++callback_count; });
    assert(replayed == 3);
    assert(callback_count == 3);

    // 删除
    assert(bntvs::deleteBusData(1) == true);
    assert(bntvs::deleteBusData(0) == false);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试信号转换单元 (SU-CONV) 的功能。
 *
 * @requirement(name="信号转换功能", id="SRS-F-06-001")
 * @requirement(name="模拟量离散量转总线信号功能", id="SRS-F-06-005")
 * 验证模拟量和离散量到总线信号的转换。
 */
static void test_su_conv_signal_conversion() {
    std::cout << "[TEST] SU-CONV: 信号转换测试...\n";

    // 模拟量转换：0V → 应编码为 0
    auto result = bntvs::convertAnalogToBus(0.0, 0x100);
    assert(result.frame_id == 0x100);
    assert(result.bus_type == "CAN");
    assert(!result.data_content.empty());

    // 模拟量转换：10V → 应编码为 4095 (12-bit)
    result = bntvs::convertAnalogToBus(10.0, 0x200);
    assert(result.data_content.size() == 2);

    // 离散量转换：高电平
    result = bntvs::convertDigitalToBus(5, 0x300);
    assert(result.data_content[0] == 1);

    // 离散量转换：低电平
    result = bntvs::convertDigitalToBus(0, 0x301);
    assert(result.data_content[0] == 0);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试总线路由单元 (SU-ROUTE) 的功能。
 *
 * @requirement(name="数据转发交换功能", id="SRS-F-07-001")
 * @requirement(name="路由寻址功能", id="SRS-F-07-002")
 * @requirement(name="以太网-CAN协议转换适配功能", id="SRS-F-07-003")
 * @requirement(name="路由功能要求", id="SRS-F-07-007")
 * 验证路由转发、协议转换和路由表管理。
 */
static void test_su_route_routing() {
    std::cout << "[TEST] SU-ROUTE: 总线路由测试...\n";

    bntvs::BusDataRecord frame;
    frame.frame_id = 0x100;

    // 路由表为空时转发应失败
    assert(bntvs::routeDataFrame(frame) == false);

    // 添加静态路由
    bntvs::RouteEntry route;
    route.dest_network = "192.168.2.0";
    route.netmask      = "255.255.255.0";
    route.next_hop     = "192.168.1.1";
    route.out_interface = "eth0";
    route.priority     = 10;
    assert(bntvs::addStaticRoute(route) == true);

    // 添加动态路由
    route.dest_network = "192.168.3.0";
    route.next_hop     = "192.168.1.2";
    assert(bntvs::addDynamicRoute(route) == true);

    // 路由转发应成功
    assert(bntvs::routeDataFrame(frame) == true);

    // 以太网↔CAN 协议转换
    auto can_frame = bntvs::convertEthernetToCAN(frame);
    assert(can_frame.bus_type == "CAN");

    auto eth_frame = bntvs::convertCANToEthernet(can_frame);
    assert(eth_frame.bus_type == "ETHERNET");

    std::cout << "  PASS\n";
}

/**
 * @brief 测试总线分析单元 (SU-ANALY) 的功能。
 *
 * @requirement(name="总线实时监听功能", id="SRS-F-09-001")
 * @requirement(name="协议解析解码功能", id="SRS-F-09-002")
 * @requirement(name="故障诊断分析功能", id="SRS-F-09-003")
 * @requirement(name="波形与时序分析功能", id="SRS-F-09-004")
 * @requirement(name="网络状态监视功能", id="SRS-F-09-006")
 * @requirement(name="错误帧识别要求", id="SRS-F-09-011")
 * 验证监听、解析、诊断、波形分析和状态监视功能。
 */
static void test_su_analy_bus_analysis() {
    std::cout << "[TEST] SU-ANALY: 总线分析测试...\n";

    // 监听启动/停止
    bool cb_called = false;
    assert(bntvs::startBusMonitoring(bntvs::BusType::CAN,
        [&cb_called](const bntvs::BusDataRecord&) { cb_called = true; }) == true);
    assert(bntvs::stopBusMonitoring() == true);

    // 协议解析
    std::vector<uint8_t> raw = {0x00, 0x00, 0x01, 0x23, 0xAA, 0xBB};
    auto parsed = bntvs::parseCANFrame(raw);
    assert(parsed.frame_id == 0x00000123);
    assert(parsed.protocol_type == "CAN2.0");

    // CAN FD 解析（>8 字节数据，但帧头仍为4字节）
    std::vector<uint8_t> raw_fd(20, 0x11);
    raw_fd[0] = 0x00; raw_fd[1] = 0x00; raw_fd[2] = 0x01; raw_fd[3] = 0xFF;
    auto parsed_fd = bntvs::parseCANFrame(raw_fd);
    assert(parsed_fd.protocol_type == "CANFD");

    // 故障诊断：正常数据
    bntvs::BusDataRecord normal_frame;
    normal_frame.data_content = {0x01, 0x02, 0x03};
    assert(bntvs::diagnoseBusFault(normal_frame) == "");

    // 故障诊断：CRC 错误（首字节为 0xFF）
    bntvs::BusDataRecord crc_error_frame;
    crc_error_frame.data_content = {0xFF, 0x00};
    assert(!bntvs::diagnoseBusFault(crc_error_frame).empty());

    // 错误帧检测
    std::vector<uint8_t> bad_data = {0xFF, 0x01};
    assert(bntvs::checkErrorFrame(bad_data) == true);
    std::vector<uint8_t> good_data = {0x01, 0x02};
    assert(bntvs::checkErrorFrame(good_data) == false);

    // 波形分析
    std::vector<double> sine;
    for (int i = 0; i < 100; ++i) {
        sine.push_back(std::sin(2.0 * 3.14159 * 10.0 * i / 100.0));
    }
    auto wf = bntvs::analyzeWaveform(sine, 1000.0);
    assert(!wf.analysis_summary.empty());
    assert(wf.signal_frequency_hz > 0);

    // 网络状态
    auto status = bntvs::getNetworkStatus(bntvs::BusType::CAN);
    assert(!status.last_update_time.empty());

    std::cout << "  PASS\n";
}

/**
 * @brief 测试故障注入单元 (SU-FAULT) 的功能。
 *
 * @requirement(name="总线短路/断路注入", id="SRS-F-12-001")
 * @requirement(name="电磁干扰注入", id="SRS-F-12-002")
 * @requirement(name="错误帧注入", id="SRS-F-12-003")
 * @requirement(name="节点离线/异常接入", id="SRS-F-12-004")
 * @requirement(name="波特率异常波动注入", id="SRS-F-12-005")
 * 验证各类故障注入功能。
 */
static void test_su_fault_fault_injection() {
    std::cout << "[TEST] SU-FAULT: 故障注入测试...\n";

    assert(bntvs::injectShortCircuit(bntvs::BusType::CAN, 100) == true);
    assert(bntvs::injectOpenCircuit(bntvs::BusType::ETHERNET, 200) == true);

    // 有效强度 (0.0~1.0)
    assert(bntvs::injectEMI(bntvs::BusType::CAN, 0.5, 100) == true);
    // 无效强度应失败
    assert(bntvs::injectEMI(bntvs::BusType::CAN, 1.5, 100) == false);

    assert(bntvs::injectErrorFrame(bntvs::BusType::CAN, "CRC错误") == true);
    assert(bntvs::injectNodeOffline("NODE_A", 500) == true);
    assert(bntvs::injectNodeAbnormal("NODE_B") == true);
    assert(bntvs::injectBaudRateAnomaly(bntvs::BusType::CAN, 50000, 300) == true);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试总线测试分析单元 (SU-TEST) 的功能。
 *
 * @requirement(name="40m内总线测试分析功能", id="SRS-F-10-001")
 * @requirement(name="40m以上总线测试分析功能", id="SRS-F-10-002")
 * @requirement(name="长时间满负荷测试分析功能", id="SRS-F-10-003")
 * 验证各类总线性能测试功能。
 */
static void test_su_test_bus_testing() {
    std::cout << "[TEST] SU-TEST: 总线测试分析测试...\n";

    auto short_result = bntvs::testShortBusPerformance(bntvs::BusType::CAN, 10);
    assert(short_result.avg_latency_us > 0);
    assert(short_result.throughput_mbps > 0);

    auto long_result = bntvs::testLongBusPerformance(bntvs::BusType::CAN, 10);
    assert(long_result.avg_latency_us > 0);

    auto stress_result = bntvs::testLongDurationStability(bntvs::BusType::CAN, 24);
    assert(stress_result.total_packets > 0);
    assert(stress_result.total_packets >= stress_result.lost_packets);

    // 长距离延迟应大于短距离
    assert(long_result.avg_latency_us >= short_result.avg_latency_us);

    std::cout << "  PASS\n";
}

/**
 * @brief 测试辅助函数。
 */
static void test_utilities() {
    std::cout << "[TEST] 辅助函数测试...\n";

    auto version = bntvs::getVersion();
    assert(!version.empty());
    assert(version.find("BNTVS_SW") != std::string::npos);

    // printHelp 仅输出，不返回值，但不应崩溃
    bntvs::printHelp();

    std::cout << "  PASS\n";
}

/**
 * @brief 主测试函数，汇总所有测试用例。
 */
int main() {
    std::cout << "========================================\n";
    std::cout << "  BNTVS_SW 单元测试\n";
    std::cout << "========================================\n\n";

    test_su_com_communication();
    test_su_prot_protocol_compat();
    test_su_stor_data_storage();
    test_su_replay_data_management();
    test_su_conv_signal_conversion();
    test_su_route_routing();
    test_su_analy_bus_analysis();
    test_su_fault_fault_injection();
    test_su_test_bus_testing();
    test_utilities();

    std::cout << "\n========================================\n";
    std::cout << "  全部测试通过!\n";
    std::cout << "========================================\n";
    return 0;
}
