//
// LDASTools frameCPP - FrameCPP Services Context Object
//
// Copyright (C) 2025 California Institute of Technology
//
// Following Peter Muldoon's "Retiring the Singleton Pattern" principles:
// - Context objects to manage multiple services
// - Explicit dependency injection
// - No global/static state
//

#ifndef FRAMECPP_FRAMECPPSERVICES_HH
#define FRAMECPP_FRAMECPPSERVICES_HH

#include "ldastoolsal/LoggerManager.hh"

namespace FrameCPP {
namespace Common {

/**
 * @brief Context object that provides access to all frameCPP services
 * 
 * This class implements the "Context Object" pattern from Peter Muldoon's
 * "Retiring the Singleton Pattern" to manage multiple services in a single
 * container. It eliminates global/static dependencies and enables:
 * 
 * - Explicit dependency injection
 * - Testable code (easy to inject mocks)
 * - Clear service lifetimes
 * - Thread-safe service access
 * 
 * @example Basic Usage
 * @code
 * int main() {
 *     // Create service dependencies
 *     auto logger_mgr = std::make_unique<LDASTools::AL::LoggerManager>();
 *     
 *     // Create services context
 *     FrameCPP::FrameCPPServices services(*logger_mgr);
 *     
 *     // Use throughout application
 *     SomeFrameCPPClass obj(services);
 *     obj.doWork();
 *     
 *     // Explicit cleanup
 *     logger_mgr->shutdown();
 *     return 0;
 * }
 * @endcode
 */
struct FrameCPPServices {
    //! Logger manager for all frameCPP logging needs
    LDASTools::AL::LoggerManager& logger_mgr;
    
    /**
     * @brief Construct services context with required dependencies
     * @param logger_manager Reference to logger manager (must outlive this object)
     */
    explicit FrameCPPServices(LDASTools::AL::LoggerManager& logger_manager) 
        : logger_mgr(logger_manager) {
    }
    
    // Delete copy/move to prevent accidental duplication
    FrameCPPServices(const FrameCPPServices&) = delete;
    FrameCPPServices& operator=(const FrameCPPServices&) = delete;
    FrameCPPServices(FrameCPPServices&&) = delete;
    FrameCPPServices& operator=(FrameCPPServices&&) = delete;
    
    /**
     * @brief Get logger for specified channel
     * @param channel Channel name (e.g., "framecpp.frtoc.data")
     * @return Pointer to logger (owned by LoggerManager)
     * @thread_safety Thread-safe
     */
    SimpleLogger* getLogger(const std::string& channel) const {
        return logger_mgr.getLogger(channel);
    }
    
    /**
     * @brief Sync all loggers with current debug levels
     * 
     * Should be called after debug levels are changed via
     * DebugLevelManager to ensure all cached loggers are updated.
     * 
     * @thread_safety Thread-safe
     */
    void syncLoggers() {
        logger_mgr.syncAllLoggers();
    }
};

} // namespace Common
} // namespace FrameCPP

#endif // FRAMECPP_FRAMECPPSERVICES_HH