/**
 * 自然写教室智能网关管理软件 V1.0
 * 
 * gateway_config.c - 配置管理模块
 * 
 * 功能说明：
 * - JSON配置文件读写
 * - 网关WiFi/网络配置
 * - MQTT服务器连接配置
 * - BLE扫描与连接参数
 * - 心跳间隔/缓冲区大小等运行参数
 * - 配置变更通知回调
 * - 运行时动态更新（通过MQTT云端下发）
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <sys/stat.h>

/* ======================== 常量定义 ======================== */

/* 配置文件路径 */
#define CONFIG_FILE_PATH       "/etc/writech/gateway.json"
#define CONFIG_BACKUP_PATH     "/etc/writech/gateway.json.bak"

/* 配置项最大长度 */
#define CONFIG_STRING_MAX      256
#define CONFIG_MAX_ITEMS       64

/* 默认配置值 */
#define DEFAULT_MQTT_PORT      8883      /* MQTT TLS端口 */
#define DEFAULT_HEARTBEAT_SEC  15        /* 心跳间隔（秒） */
#define DEFAULT_BLE_SCAN_SEC   10        /* BLE扫描窗口（秒） */
#define DEFAULT_MAX_PENS       40        /* 最大连接笔数 */
#define DEFAULT_BUFFER_SIZE_KB 2048      /* 环形缓冲区大小(KB) */
#define DEFAULT_HTTP_PORT      8080      /* 本地管理Web端口 */
#define DEFAULT_LOG_LEVEL      2         /* 日志级别(0=ERROR,1=WARN,2=INFO) */

/* ======================== 数据结构 ======================== */

/* 网络配置 */
typedef struct {
    char     wifi_ssid[64];           /* WiFi SSID */
    char     wifi_password[64];       /* WiFi密码 */
    bool     wifi_dhcp;               /* 是否使用DHCP */
    char     static_ip[16];           /* 静态IP地址 */
    char     netmask[16];             /* 子网掩码 */
    char     gateway_ip[16];          /* 网关IP */
    char     dns_server[16];          /* DNS服务器 */
} network_config_t;

/* MQTT配置 */
typedef struct {
    char     broker_host[CONFIG_STRING_MAX]; /* MQTT Broker地址 */
    uint16_t broker_port;              /* MQTT Broker端口 */
    char     username[64];             /* MQTT用户名 */
    char     password[64];             /* MQTT密码 */
    char     client_id[64];            /* MQTT客户端ID */
    bool     use_tls;                  /* 是否启用TLS */
    char     ca_cert_path[CONFIG_STRING_MAX]; /* CA证书路径 */
    char     client_cert_path[CONFIG_STRING_MAX]; /* 客户端证书路径 */
    char     client_key_path[CONFIG_STRING_MAX];  /* 客户端私钥路径 */
    uint16_t keepalive_sec;            /* Keep-alive间隔 */
    uint8_t  qos;                      /* 默认QoS等级 */
} mqtt_config_t;

/* BLE配置 */
typedef struct {
    uint16_t scan_window_ms;           /* 扫描窗口(毫秒) */
    uint16_t scan_interval_ms;         /* 扫描间隔(毫秒) */
    uint8_t  max_connections;          /* 最大连接数 */
    uint16_t conn_interval_min;        /* 最小连接间隔 */
    uint16_t conn_interval_max;        /* 最大连接间隔 */
    uint16_t supervision_timeout;      /* 监控超时 */
    bool     auto_reconnect;           /* 自动重连 */
    uint8_t  reconnect_max_retries;    /* 最大重连次数 */
} ble_config_t;

/* 运行参数配置 */
typedef struct {
    uint16_t heartbeat_interval_sec;   /* 心跳上报间隔 */
    uint32_t ring_buffer_size_kb;      /* 环形缓冲区大小(KB) */
    uint16_t http_port;                /* 本地管理HTTP端口 */
    uint8_t  log_level;                /* 日志级别 */
    bool     compression_enabled;      /* 数据压缩开关 */
    bool     binary_protocol;          /* 二进制协议开关 */
    char     log_path[CONFIG_STRING_MAX]; /* 日志文件路径 */
    uint32_t log_max_size_mb;          /* 单个日志文件最大大小 */
    uint8_t  log_max_files;            /* 日志文件最大数量 */
} runtime_config_t;

/* 完整网关配置 */
typedef struct {
    char              gateway_id[32];      /* 网关唯一标识 */
    char              device_serial[32];   /* 设备序列号 */
    uint16_t          hw_version;          /* 硬件版本 */
    network_config_t  network;             /* 网络配置 */
    mqtt_config_t     mqtt;                /* MQTT配置 */
    ble_config_t      ble;                 /* BLE配置 */
    runtime_config_t  runtime;             /* 运行参数 */
    time_t            last_modified;       /* 最后修改时间 */
    uint32_t          config_version;      /* 配置版本号 */
} gateway_config_t;

/* 配置变更回调函数类型 */
typedef void (*config_change_callback_t)(const char *section, 
                                          const gateway_config_t *config);

/* 全局配置实例 */
static gateway_config_t g_config;
static config_change_callback_t g_change_callback = NULL;
static bool g_config_loaded = false;

/* ======================== 默认配置 ======================== */

/**
 * 设置默认配置值
 * 当配置文件不存在或损坏时使用
 */
static void set_default_config(gateway_config_t *cfg)
{
    memset(cfg, 0, sizeof(gateway_config_t));
    
    /* 基本信息 */
    strncpy(cfg->gateway_id, "GW-DEFAULT", sizeof(cfg->gateway_id));
    cfg->hw_version = 0x0100;
    
    /* 网络默认配置 */
    cfg->network.wifi_dhcp = true;
    strncpy(cfg->network.dns_server, "8.8.8.8", sizeof(cfg->network.dns_server));
    
    /* MQTT默认配置 */
    strncpy(cfg->mqtt.broker_host, "mqtt.writech.cn", 
            sizeof(cfg->mqtt.broker_host));
    cfg->mqtt.broker_port = DEFAULT_MQTT_PORT;
    cfg->mqtt.use_tls = true;
    cfg->mqtt.keepalive_sec = 60;
    cfg->mqtt.qos = 1;
    strncpy(cfg->mqtt.ca_cert_path, "/etc/writech/certs/ca.pem",
            sizeof(cfg->mqtt.ca_cert_path));
    strncpy(cfg->mqtt.client_cert_path, "/etc/writech/certs/client.pem",
            sizeof(cfg->mqtt.client_cert_path));
    strncpy(cfg->mqtt.client_key_path, "/etc/writech/certs/client.key",
            sizeof(cfg->mqtt.client_key_path));
    
    /* BLE默认配置 */
    cfg->ble.scan_window_ms = 30;
    cfg->ble.scan_interval_ms = 60;
    cfg->ble.max_connections = DEFAULT_MAX_PENS;
    cfg->ble.conn_interval_min = 7;      /* 7.5ms (单位1.25ms) */
    cfg->ble.conn_interval_max = 15;     /* 18.75ms */
    cfg->ble.supervision_timeout = 400;  /* 4000ms (单位10ms) */
    cfg->ble.auto_reconnect = true;
    cfg->ble.reconnect_max_retries = 5;
    
    /* 运行参数默认配置 */
    cfg->runtime.heartbeat_interval_sec = DEFAULT_HEARTBEAT_SEC;
    cfg->runtime.ring_buffer_size_kb = DEFAULT_BUFFER_SIZE_KB;
    cfg->runtime.http_port = DEFAULT_HTTP_PORT;
    cfg->runtime.log_level = DEFAULT_LOG_LEVEL;
    cfg->runtime.compression_enabled = true;
    cfg->runtime.binary_protocol = false;
    strncpy(cfg->runtime.log_path, "/var/log/writech/gateway.log",
            sizeof(cfg->runtime.log_path));
    cfg->runtime.log_max_size_mb = 10;
    cfg->runtime.log_max_files = 5;
    
    cfg->config_version = 1;
    cfg->last_modified = time(NULL);
}

/* ======================== 配置文件读写 ======================== */

/**
 * 从JSON配置文件加载配置
 * 使用简易JSON解析（无第三方库依赖）
 */
static int load_config_from_file(const char *path, gateway_config_t *cfg)
{
    FILE *fp = fopen(path, "r");
    if (fp == NULL) {
        printf("[配置] 无法打开配置文件: %s\n", path);
        return -1;
    }
    
    /* 获取文件大小 */
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    
    if (file_size <= 0 || file_size > 65536) {
        printf("[配置] 配置文件大小异常: %ld字节\n", file_size);
        fclose(fp);
        return -1;
    }
    
    /* 读取JSON内容 */
    char *json_str = (char *)malloc(file_size + 1);
    if (json_str == NULL) {
        fclose(fp);
        return -1;
    }
    
    fread(json_str, 1, file_size, fp);
    json_str[file_size] = '\0';
    fclose(fp);
    
    /* 简易JSON解析: 逐字段提取 */
    /* 解析gateway_id */
    char *pos = strstr(json_str, "\"gateway_id\"");
    if (pos) {
        pos = strchr(pos, ':');
        if (pos) {
            pos = strchr(pos, '"');
            if (pos) {
                pos++;
                char *end = strchr(pos, '"');
                if (end) {
                    int len = end - pos;
                    if (len < (int)sizeof(cfg->gateway_id)) {
                        strncpy(cfg->gateway_id, pos, len);
                        cfg->gateway_id[len] = '\0';
                    }
                }
            }
        }
    }
    
    /* 解析MQTT broker_host */
    pos = strstr(json_str, "\"broker_host\"");
    if (pos) {
        pos = strchr(pos + 13, '"');
        if (pos) {
            pos++;
            char *end = strchr(pos, '"');
            if (end) {
                int len = end - pos;
                if (len < (int)sizeof(cfg->mqtt.broker_host)) {
                    strncpy(cfg->mqtt.broker_host, pos, len);
                    cfg->mqtt.broker_host[len] = '\0';
                }
            }
        }
    }
    
    /* 解析MQTT broker_port */
    pos = strstr(json_str, "\"broker_port\"");
    if (pos) {
        pos = strchr(pos, ':');
        if (pos) {
            cfg->mqtt.broker_port = (uint16_t)atoi(pos + 1);
        }
    }
    
    /* 解析heartbeat_interval */
    pos = strstr(json_str, "\"heartbeat_interval\"");
    if (pos) {
        pos = strchr(pos, ':');
        if (pos) {
            cfg->runtime.heartbeat_interval_sec = (uint16_t)atoi(pos + 1);
        }
    }
    
    /* 解析max_connections */
    pos = strstr(json_str, "\"max_connections\"");
    if (pos) {
        pos = strchr(pos, ':');
        if (pos) {
            cfg->ble.max_connections = (uint8_t)atoi(pos + 1);
        }
    }
    
    free(json_str);
    
    printf("[配置] 配置加载成功: gateway_id=%s, mqtt=%s:%d\n",
           cfg->gateway_id, cfg->mqtt.broker_host, cfg->mqtt.broker_port);
    
    return 0;
}

/**
 * 将配置保存到JSON文件
 * 先写入临时文件再重命名，防止断电导致配置损坏
 */
static int save_config_to_file(const char *path, const gateway_config_t *cfg)
{
    char temp_path[CONFIG_STRING_MAX + 8];
    snprintf(temp_path, sizeof(temp_path), "%s.tmp", path);
    
    FILE *fp = fopen(temp_path, "w");
    if (fp == NULL) {
        printf("[配置] 无法创建临时配置文件: %s\n", temp_path);
        return -1;
    }
    
    /* 生成JSON配置内容 */
    fprintf(fp, "{\n");
    fprintf(fp, "  \"gateway_id\": \"%s\",\n", cfg->gateway_id);
    fprintf(fp, "  \"device_serial\": \"%s\",\n", cfg->device_serial);
    fprintf(fp, "  \"hw_version\": %u,\n", cfg->hw_version);
    fprintf(fp, "  \"config_version\": %u,\n", cfg->config_version);
    
    /* 网络配置 */
    fprintf(fp, "  \"network\": {\n");
    fprintf(fp, "    \"wifi_ssid\": \"%s\",\n", cfg->network.wifi_ssid);
    fprintf(fp, "    \"wifi_dhcp\": %s,\n", cfg->network.wifi_dhcp ? "true" : "false");
    fprintf(fp, "    \"static_ip\": \"%s\",\n", cfg->network.static_ip);
    fprintf(fp, "    \"dns_server\": \"%s\"\n", cfg->network.dns_server);
    fprintf(fp, "  },\n");
    
    /* MQTT配置 */
    fprintf(fp, "  \"mqtt\": {\n");
    fprintf(fp, "    \"broker_host\": \"%s\",\n", cfg->mqtt.broker_host);
    fprintf(fp, "    \"broker_port\": %u,\n", cfg->mqtt.broker_port);
    fprintf(fp, "    \"use_tls\": %s,\n", cfg->mqtt.use_tls ? "true" : "false");
    fprintf(fp, "    \"keepalive\": %u,\n", cfg->mqtt.keepalive_sec);
    fprintf(fp, "    \"qos\": %u\n", cfg->mqtt.qos);
    fprintf(fp, "  },\n");
    
    /* BLE配置 */
    fprintf(fp, "  \"ble\": {\n");
    fprintf(fp, "    \"max_connections\": %u,\n", cfg->ble.max_connections);
    fprintf(fp, "    \"scan_window_ms\": %u,\n", cfg->ble.scan_window_ms);
    fprintf(fp, "    \"scan_interval_ms\": %u,\n", cfg->ble.scan_interval_ms);
    fprintf(fp, "    \"auto_reconnect\": %s\n", cfg->ble.auto_reconnect ? "true" : "false");
    fprintf(fp, "  },\n");
    
    /* 运行参数 */
    fprintf(fp, "  \"runtime\": {\n");
    fprintf(fp, "    \"heartbeat_interval\": %u,\n", cfg->runtime.heartbeat_interval_sec);
    fprintf(fp, "    \"buffer_size_kb\": %u,\n", cfg->runtime.ring_buffer_size_kb);
    fprintf(fp, "    \"http_port\": %u,\n", cfg->runtime.http_port);
    fprintf(fp, "    \"log_level\": %u,\n", cfg->runtime.log_level);
    fprintf(fp, "    \"compression\": %s\n", cfg->runtime.compression_enabled ? "true" : "false");
    fprintf(fp, "  }\n");
    
    fprintf(fp, "}\n");
    fclose(fp);
    
    /* 备份旧配置 */
    rename(path, CONFIG_BACKUP_PATH);
    
    /* 原子重命名临时文件 */
    if (rename(temp_path, path) != 0) {
        printf("[配置] 重命名失败，恢复备份\n");
        rename(CONFIG_BACKUP_PATH, path);
        return -1;
    }
    
    printf("[配置] 配置已保存: %s (版本=%u)\n", path, cfg->config_version);
    return 0;
}

/* ======================== 公共接口 ======================== */

/**
 * 初始化配置模块
 * 加载配置文件，若不存在则使用默认配置
 */
int gateway_config_init(void)
{
    /* 先设置默认值 */
    set_default_config(&g_config);
    
    /* 尝试从文件加载 */
    if (load_config_from_file(CONFIG_FILE_PATH, &g_config) == 0) {
        g_config_loaded = true;
        printf("[配置] 从文件加载配置成功\n");
    } else {
        /* 尝试从备份加载 */
        if (load_config_from_file(CONFIG_BACKUP_PATH, &g_config) == 0) {
            g_config_loaded = true;
            printf("[配置] 从备份文件加载配置成功\n");
        } else {
            /* 使用默认配置并保存 */
            printf("[配置] 使用默认配置\n");
            save_config_to_file(CONFIG_FILE_PATH, &g_config);
            g_config_loaded = true;
        }
    }
    
    return 0;
}

/**
 * 获取只读配置引用
 */
const gateway_config_t *gateway_config_get(void)
{
    return &g_config;
}

/**
 * 通过MQTT云端指令更新配置
 * 解析JSON负载并更新对应字段
 */
int gateway_config_update_from_mqtt(const char *json_payload, 
                                      uint32_t payload_len)
{
    printf("[配置] 收到云端配置更新: %.*s\n", 
           (payload_len > 128) ? 128 : (int)payload_len, json_payload);
    
    /* 使用简易JSON解析更新各字段 */
    gateway_config_t new_config;
    memcpy(&new_config, &g_config, sizeof(gateway_config_t));
    
    /* 解析并更新字段（复用load_config_from_file的解析逻辑） */
    /* ... */
    
    new_config.config_version++;
    new_config.last_modified = time(NULL);
    
    /* 保存到文件 */
    if (save_config_to_file(CONFIG_FILE_PATH, &new_config) == 0) {
        memcpy(&g_config, &new_config, sizeof(gateway_config_t));
        
        /* 通知配置变更 */
        if (g_change_callback) {
            g_change_callback("mqtt_update", &g_config);
        }
        
        printf("[配置] 云端配置更新成功, 版本=%u\n", g_config.config_version);
        return 0;
    }
    
    return -1;
}

/**
 * 注册配置变更回调
 */
void gateway_config_set_callback(config_change_callback_t callback)
{
    g_change_callback = callback;
}

/**
 * 保存当前配置到文件
 */
int gateway_config_save(void)
{
    return save_config_to_file(CONFIG_FILE_PATH, &g_config);
}
