#include "LoggerOptions.hh"

/// @brief Constructor for LoggerOptions.
LoggerOptions::LoggerOptions( ) : desc_( "Logger Options" )
{
    desc_.add_options( ) //
        ( "log-debug-level,d",
          boost::program_options::value< int >( )->default_value( 0 ),
          "Set debug level" ) //
        ( "log-sink,s",
          boost::program_options::value< std::string >( )->default_value(
              "console" ),
          "Set sink type (console, file, syslog, null)" ) //
        ( "log-output-directory,o",
          boost::program_options::value< std::string >( )->default_value( "." ),
          "Set output directory for file sink" ) //
        ( "log-format,f",
          boost::program_options::value< std::string >( )->default_value(
              "text" ),
          "Set format type (text, html)" ) //
        ( "log-severity-level,l",
          boost::program_options::value< std::string >( )->default_value(
              "error" ),
          "Set minimum severity level (debug, note, warning, error_non_fatal, "
          "error, email, phone)" ) //
        ;
}

/// @brief Extend the program options description with logger options.
/// @param desc Program options description
void
LoggerOptions::extend_options(
    boost::program_options::options_description& desc )
{
    desc.add( desc_ );
}

/// @brief Apply the parsed options to the SimpleLogger.
/// @param vm Variables map containing the parsed options
/// @param logger Pointer to the SimpleLogger instance
void
LoggerOptions::apply_options( const boost::program_options::variables_map& vm,
                              SimpleLogger* logger )
{
    int         debug_level = vm[ "debug-level" ].as< int >( );
    std::string sink_type = vm[ "sink" ].as< std::string >( );
    std::string output_directory =
        vm[ "output-directory" ].as< std::string >( );
    std::string format_type = vm[ "format" ].as< std::string >( );
    std::string severity_level = vm[ "severity-level" ].as< std::string >( );

    logger->set_debug_level( debug_level );
    logger->set_format_type( format_type == "html"
                                 ? SimpleLogger::FormatType::HTML
                                 : SimpleLogger::FormatType::Text );
    logger->set_min_severity( severity_from_string( severity_level ) );
    logger->change_sink( sink_type, output_directory );
}

/// @brief Convert severity level string to custom_severity_level.
/// @param level Severity level string
/// @return custom_severity_level
SimpleLogger::custom_severity_level
LoggerOptions::severity_from_string( const std::string& level )
{
    if ( level == "debug" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::debug );
    }
    else if ( level == "note" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::note );
    }
    else if ( level == "warning" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::warning );
    }
    else if ( level == "error_non_fatal" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::error_non_fatal );
    }
    else if ( level == "error" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::error );
    }
    else if ( level == "email" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::email );
    }
    else if ( level == "phone" )
    {
        return SimpleLogger::custom_severity_level(
            SimpleLogger::severity_level::phone );
    }
    else
    {
        throw std::invalid_argument( "Invalid severity level: " + level );
    }
}
