#include "config.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <boost/filesystem.hpp>

namespace jtjai_media {

bool ConfigManager::load_from_file(const std::string& config_file) {
    try {
        std::ifstream file(config_file);
        if (!file.is_open()) {
            std::cerr << "无法打开配置文件: " << config_file << std::endl;
            return false;
        }
        
        std::stringstream buffer;
        buffer << file.rdbuf();
        file.close();
        
        return load_from_json(buffer.str());
    } catch (const std::exception& e) {
        std::cerr << "加载配置文件时发生异常: " << e.what() << std::endl;
        return false;
    }
}

bool ConfigManager::load_from_json(const std::string& json_str) {
    try {
        auto json_value = boost::json::parse(json_str);
        auto json_obj = json_value.as_object();
        
        // 加载全局配置
        if (json_obj.contains("global_config")) {
            global_config_ = global_config_from_json(json_obj["global_config"].as_object());
        }
        
        // 加载流配置
        stream_configs_.clear();
        if (json_obj.contains("streams")) {
            auto streams_array = json_obj["streams"].as_array();
            for (const auto& stream_json : streams_array) {
                stream_configs_.push_back(stream_config_from_json(stream_json.as_object()));
            }
        }
        
        return validate();
    } catch (const std::exception& e) {
        std::cerr << "解析JSON配置时发生异常: " << e.what() << std::endl;
        return false;
    }
}

bool ConfigManager::save_to_file(const std::string& config_file) const {
    try {
        boost::json::object root;
        
        // 保存全局配置
        root["global_config"] = global_config_to_json(global_config_);
        
        // 保存流配置
        boost::json::array streams_array;
        for (const auto& stream : stream_configs_) {
            streams_array.push_back(stream_config_to_json(stream));
        }
        root["streams"] = streams_array;
        
        std::ofstream file(config_file);
        if (!file.is_open()) {
            std::cerr << "无法创建配置文件: " << config_file << std::endl;
            return false;
        }
        
        file << boost::json::serialize(root) << std::endl;
        file.close();
        
        return true;
    } catch (const std::exception& e) {
        std::cerr << "保存配置文件时发生异常: " << e.what() << std::endl;
        return false;
    }
}

bool ConfigManager::validate() const {
    // 检查全局配置
    if (global_config_.total_poll_duration_seconds <= 0) {
        std::cerr << "总轮询时长必须大于0秒" << std::endl;
        return false;
    }
    
    if (global_config_.max_concurrent_streams <= 0) {
        std::cerr << "最大并发流数必须大于0" << std::endl;
        return false;
    }
    
    if (global_config_.output_directory.empty()) {
        std::cerr << "输出目录不能为空" << std::endl;
        return false;
    }
    
    // 检查流配置
    if (stream_configs_.empty()) {
        std::cerr << "至少需要配置一个RTSP流" << std::endl;
        return false;
    }
    
    for (size_t i = 0; i < stream_configs_.size(); ++i) {
        const auto& stream = stream_configs_[i];
        
        if (stream.rtsp_url.empty()) {
            std::cerr << "第 " << (i + 1) << " 个流的RTSP地址不能为空" << std::endl;
            return false;
        }
        
        if (stream.duration_seconds <= 0) {
            std::cerr << "第 " << (i + 1) << " 个流的访问时长必须大于0秒" << std::endl;
            return false;
        }
        
        if (stream.weight <= 0) {
            std::cerr << "第 " << (i + 1) << " 个流的权重必须大于0" << std::endl;
            return false;
        }
        
        if (stream.output_filename.empty()) {
            std::cerr << "第 " << (i + 1) << " 个流的输出文件名不能为空" << std::endl;
            return false;
        }
    }
    
    return true;
}

std::string ConfigManager::to_string() const {
    std::stringstream ss;
    ss << "全局配置:\\n";
    ss << "  总轮询时长: " << global_config_.total_poll_duration_seconds << " 秒\\n";
    ss << "  最大并发流数: " << global_config_.max_concurrent_streams << "\\n";
    ss << "  输出目录: " << global_config_.output_directory << "\\n";
    ss << "  报告文件名: " << global_config_.report_filename << "\\n";
    ss << "  连接超时: " << global_config_.connection_timeout_seconds << " 秒\\n";
    ss << "  读取超时: " << global_config_.read_timeout_seconds << " 秒\\n";
    ss << "  轮询周期数: " << (global_config_.poll_cycles == -1 ? "无限循环" : std::to_string(global_config_.poll_cycles)) << "\n";
    ss << "  周期间隔: " << global_config_.cycle_interval_seconds << " 秒\n";
    
    ss << "\\n流配置 (" << stream_configs_.size() << " 个):\\n";
    for (size_t i = 0; i < stream_configs_.size(); ++i) {
        const auto& stream = stream_configs_[i];
        ss << "  [" << (i + 1) << "] " << stream.rtsp_url << "\\n";
        ss << "      时长: " << stream.duration_seconds << " 秒, ";
        ss << "权重: " << stream.weight << ", ";
        ss << "输出: " << stream.output_filename << "\\n";
    }
    
    return ss.str();
}

boost::json::object ConfigManager::stream_config_to_json(const StreamConfig& config) const {
    boost::json::object obj;
    obj["rtsp_url"] = config.rtsp_url;
    obj["duration_seconds"] = config.duration_seconds;
    obj["weight"] = config.weight;
    obj["output_filename"] = config.output_filename;
    return obj;
}

StreamConfig ConfigManager::stream_config_from_json(const boost::json::object& json_obj) const {
    StreamConfig config;
    
    if (json_obj.contains("rtsp_url")) {
        config.rtsp_url = json_obj.at("rtsp_url").as_string().c_str();
    }
    
    if (json_obj.contains("duration_seconds")) {
        config.duration_seconds = static_cast<int>(json_obj.at("duration_seconds").as_int64());
    }
    
    if (json_obj.contains("weight")) {
        config.weight = json_obj.at("weight").as_double();
    }
    
    if (json_obj.contains("output_filename")) {
        config.output_filename = json_obj.at("output_filename").as_string().c_str();
    }
    
    return config;
}

boost::json::object ConfigManager::global_config_to_json(const GlobalConfig& config) const {
    boost::json::object obj;
    obj["total_poll_duration_seconds"] = config.total_poll_duration_seconds;
    obj["max_concurrent_streams"] = config.max_concurrent_streams;
    obj["output_directory"] = config.output_directory;
    obj["report_filename"] = config.report_filename;
    obj["connection_timeout_seconds"] = config.connection_timeout_seconds;
    obj["read_timeout_seconds"] = config.read_timeout_seconds;
    obj["poll_cycles"] = config.poll_cycles;
    obj["cycle_interval_seconds"] = config.cycle_interval_seconds;
    return obj;
}

GlobalConfig ConfigManager::global_config_from_json(const boost::json::object& json_obj) const {
    GlobalConfig config;
    
    if (json_obj.contains("total_poll_duration_seconds")) {
        config.total_poll_duration_seconds = static_cast<int>(json_obj.at("total_poll_duration_seconds").as_int64());
    }
    
    if (json_obj.contains("max_concurrent_streams")) {
        config.max_concurrent_streams = static_cast<int>(json_obj.at("max_concurrent_streams").as_int64());
    }
    
    if (json_obj.contains("output_directory")) {
        config.output_directory = json_obj.at("output_directory").as_string().c_str();
    }
    
    if (json_obj.contains("report_filename")) {
        config.report_filename = json_obj.at("report_filename").as_string().c_str();
    }
    
    if (json_obj.contains("connection_timeout_seconds")) {
        config.connection_timeout_seconds = static_cast<int>(json_obj.at("connection_timeout_seconds").as_int64());
    }
    
    if (json_obj.contains("read_timeout_seconds")) {
        config.read_timeout_seconds = static_cast<int>(json_obj.at("read_timeout_seconds").as_int64());
    }
    
    if (json_obj.contains("poll_cycles")) {
        config.poll_cycles = static_cast<int>(json_obj.at("poll_cycles").as_int64());
    }
    
    if (json_obj.contains("cycle_interval_seconds")) {
        config.cycle_interval_seconds = static_cast<int>(json_obj.at("cycle_interval_seconds").as_int64());
    }
    
    return config;
}

} // namespace jtjai_media