//
// LDASTools frameCPP - frameCPP-Specific Debug Level Manager Implementation
//
// Copyright (C) 2025 California Institute of Technology
//
// LDASTools frameCPP is free software; you may redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 (GPLv2) of the
// License or at your discretion, any later version.
//

#include "FrameCPPDebugManager.hh"
#include "framecpp/Common/FrameCPPServices.hh"
#include "ldastoolsal/LoggerRegistry.hh"
#include "ldastoolsal/LoggerManager.hh"
#include <iostream>
#include <sstream>

namespace FrameCPP {
namespace Utilities {

// Static member definition - survives static destruction
int FrameCPPDebugManager::cached_global_level_ = 0;

std::string FrameCPPDebugManager::get_available_channels_help() {
    std::ostringstream oss;
    
    oss << "\nAvailable Debug Channels:\n";
    
    // 1. Show configured channels (from environment/command line)
    auto configured_channels = get_channel_configs();
    if (!configured_channels.empty()) {
        oss << "\nConfigured Channels:\n";
        for (const auto& config : configured_channels) {
            oss << "  " << config.pattern << " -> level " << config.level << "\n";
        }
    }
    
    // 2. Show active channels (currently instantiated)
    auto active_channels = LDASTools::AL::LoggerRegistry::getInstance().get_all_logger_names();
    if (!active_channels.empty()) {
        oss << "\nActive Channels (currently instantiated):\n";
        for (const auto& channel : active_channels) {
            int level = get_channel_level(channel);
            oss << "  " << channel << " (effective level: " << level << ")\n";
        }
    }
    
    // 3. Show frameCPP example channels  
    oss << "\nFrameCPP Example Channels:\n";
    oss << "  framecpp.frheader         FrHeader I/O and verification\n";
    oss << "  framecpp.frtoc.*          All FrTOC components\n";
    oss << "  framecpp.frtoc.data       FrTOC data operations\n";
    oss << "  framecpp.frtoc.adcdata    FrTOC ADC data handling\n";
    oss << "  framecpp.frtoc.procdata   FrTOC processed data handling\n";
    oss << "  framecpp.frtoc.simdata    FrTOC simulation data handling\n";
    oss << "  framecpp.frtoc.serdata    FrTOC serial data handling\n";
    oss << "  framecpp.frtoc.statdata   FrTOC static data handling\n";
    oss << "  framecpp.frtoc.summary    FrTOC summary data handling\n";
    oss << "  framecpp.frtoc.event      FrTOC event data handling\n";
    oss << "  framecpp.frtoc.simevent   FrTOC simulation event handling\n";
    oss << "  framecpp.frendoffile      FrEndOfFile processing\n";
    oss << "  framecpp.archive.walking  Container walking and recursive object inspection\n";
    oss << "  framecpp.*                All framecpp modules\n";
    
    oss << "\nUsage Examples:\n";
    oss << "  export FRAMECPP_DEBUG_LEVEL=20\n";
    oss << "  export FRAMECPP_DEBUG_CHANNELS=\"framecpp.frheader:25,framecpp.frtoc.*:30\"\n";
    oss << "  --debug-level=15 --debug-channels=\"framecpp.frendoffile:40\"\n";
    oss << "  --debug-channels=\"framecpp.archive.walking:25\" --walk-containers\n";
    
    return oss.str();
}

bool FrameCPPDebugManager::initialize_with_services(int argc, char* argv[], 
                                                   Common::FrameCPPServices& services,
                                                   const std::string& program_name) {
    // Register frameCPP-specific callbacks before initialization
    set_help_callback(get_available_channels_help);
    set_library_name("framecpp");
    set_env_prefix("FRAMECPP_DEBUG");
    set_example_channels({
        "framecpp.frtoc.*",
        "framecpp.frendoffile", 
        "framecpp.*"
    });
    
    // Initialize with frameCPP environment prefix
    bool result = LDASTools::AL::DebugLevelManager::initialize(
        argc, argv, program_name, "FRAMECPP_DEBUG");
        
    // Sync the LoggerManager with current debug levels
    if (result) {
        sync_services_loggers(services);
    }
    return result;
}

void FrameCPPDebugManager::sync_services_loggers(Common::FrameCPPServices& services) {
    // Sync the LoggerManager with current debug levels from DebugLevelManager
    services.syncLoggers();
    
    // Also sync any legacy cached loggers for compatibility
    sync_all_cached_loggers();
}

// All debug option handling is now delegated to the base class
// through callback registration in initialize()

int FrameCPPDebugManager::get_safe_global_level() {
    // Return cached value that survives static destruction
    return cached_global_level_;
}

void FrameCPPDebugManager::set_global_level_with_cache(int level) {
    // Set both the normal debug level and cache it for static destruction
    LDASTools::AL::DebugLevelManager::set_global_level(level);
    cached_global_level_ = level;
}

} // namespace Utilities
} // namespace FrameCPP