/********************************************************************
* CONFIDENTIAL - All source code is the propriety and confidential  *
* information of David Sorber.                                      *
*                                                                   *
* Copyright 2024 David Sorber                                       *
* Unpublished -- all rights reserved under the copyright laws       *
* of the United States.                                             *
********************************************************************/

#include <cstdio>
#include <chrono>
#include <stdexcept>

#include "Logger.h"


DBS::Logger::Logger(CopyManagerOptions* configObj)
    : r_options(*configObj)
{
    m_outputStream.str("");
    m_logFile.open("loggy"/*r_config.getLogPath()*/, std::ios::out | std::ios::app);
    if (! m_logFile)
    {
        throw std::runtime_error("Unable to open log file: " /*+ r_config.getLogPath()*/);
    }
}

DBS::Logger::~Logger()
{
    m_logFile.close();
}

void DBS::Logger::log_msg(
    enum LOG_LEVEL level,
    const std::string& msg)
{
    if (level > 3)//r_config.getLogLevel())
    {
        return;
    }

    struct timeval tv;
    struct tm *tm;
    gettimeofday(&tv, NULL);
    tm = localtime(&tv.tv_sec);

    char time_format[64], time_str[64];

    const bool LOG_WITH_MILLISECONDS = true;
    if (LOG_WITH_MILLISECONDS == true)
    {
        // Set format to include milliseconds
        strftime(time_format, sizeof(time_format), "%a %b %d %H:%M:%S.%%03u %Y",
                 tm);
        std::snprintf(time_str, sizeof(time_str), time_format, (tv.tv_usec / 1000));
    }
    else
    {
        // Set format to not include milliseconds
        strftime(time_str, sizeof(time_str), "%a %b %d %H:%M:%S %Y", tm);
    }

    // NOTE: "COMPONENT_ID" must be defined somewhere, ideally at compile time
    switch (level)
    {
        case error:
            m_logFile << time_str << "|ERROR|copytool|" << msg << std::endl;
            break;

        case warn:
            m_logFile << time_str << "|WARNING|copytool|" << msg << std::endl;
            break;

        case info:
            m_logFile << time_str << "|INFO|copytool|" << msg << std::endl;
            break;

        case debug:
            m_logFile << time_str << "|DEBUG|copytool|" << msg << std::endl;
            break;

        case trace:
            m_logFile << time_str << "|TRACE|copytool|" << msg << std::endl;
            break;

        default:
            break;
    }
}