//===-- Log.cpp -------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <pthread.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>

// C++ Includes
#include <map>
#include <string>

// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Host/Mutex.h"

using namespace lldb;
using namespace lldb_private;

Log::Log () :
    m_stream_sp(),
    m_options(0),
    m_mask_bits(0)
{
}

Log::Log (StreamSP &stream_sp) :
    m_stream_sp(stream_sp),
    m_options(0),
    m_mask_bits(0)
{
}

Log::~Log ()
{
}

Flags &
Log::GetOptions()
{
    return m_options;
}

const Flags &
Log::GetOptions() const
{
    return m_options;
}

Flags &
Log::GetMask()
{
    return m_mask_bits;
}

const Flags &
Log::GetMask() const
{
    return m_mask_bits;
}


//----------------------------------------------------------------------
// All logging eventually boils down to this function call. If we have
// a callback registered, then we call the logging callback. If we have
// a valid file handle, we also log to the file.
//----------------------------------------------------------------------
void
Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
{
    if (m_stream_sp)
    {
        static uint32_t g_sequence_id = 0;
        StreamString header;
        static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);

        Mutex::Locker locker;

        uint32_t log_options = m_options.GetAllFlagBits();

        // Lock the threaded logging mutex if we are doing thread safe logging
        if (log_options & LLDB_LOG_OPTION_THREADSAFE)
            locker.Reset(g_LogThreadedMutex.GetMutex());

        // Add a sequence ID if requested
        if (log_options & LLDB_LOG_OPTION_PREPEND_SEQUENCE)
            header.Printf ("%u ", ++g_sequence_id);

        // Timestamp if requested
        if (log_options & LLDB_LOG_OPTION_PREPEND_TIMESTAMP)
        {
            struct timeval tv = TimeValue::Now().GetAsTimeVal();
            header.Printf ("%9llu.%6.6llu ", tv.tv_sec, tv.tv_usec);
        }

        // Add the process and thread if requested
        if (log_options & LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD)
            header.Printf ("[%4.4x/%4.4x]: ", getpid(), Host::GetCurrentThreadID());

        // Add the process and thread if requested
        if (log_options & LLDB_LOG_OPTION_PREPEND_THREAD_NAME)
        {
            const char *thread_name_str = Host::GetThreadName (getpid(), Host::GetCurrentThreadID());
            if (thread_name_str)
                header.Printf ("%s ", thread_name_str);
        }

        header.PrintfVarArg (format, args);
        m_stream_sp->Printf("%s\n", header.GetData());
    }
}


void
Log::PutCString (const char *cstr)
{
    Printf ("%s", cstr);
}


//----------------------------------------------------------------------
// Simple variable argument logging with flags.
//----------------------------------------------------------------------
void
Log::Printf(const char *format, ...)
{
    va_list args;
    va_start (args, format);
    PrintfWithFlagsVarArg (0, format, args);
    va_end (args);
}

void
Log::VAPrintf (const char *format, va_list args)
{
    PrintfWithFlagsVarArg (0, format, args);
}


//----------------------------------------------------------------------
// Simple variable argument logging with flags.
//----------------------------------------------------------------------
void
Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
{
    va_list args;
    va_start (args, format);
    PrintfWithFlagsVarArg (flags, format, args);
    va_end (args);
}

//----------------------------------------------------------------------
// Print debug strings if and only if the global debug option is set to
// a non-zero value.
//----------------------------------------------------------------------
void
Log::Debug (const char *format, ...)
{
    if (GetOptions().IsSet(LLDB_LOG_OPTION_DEBUG))
    {
        va_list args;
        va_start (args, format);
        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
        va_end (args);
    }
}


//----------------------------------------------------------------------
// Print debug strings if and only if the global debug option is set to
// a non-zero value.
//----------------------------------------------------------------------
void
Log::DebugVerbose (const char *format, ...)
{
    if (GetOptions().IsSet(LLDB_LOG_OPTION_DEBUG) && GetOptions().IsSet(LLDB_LOG_OPTION_VERBOSE))
    {
        va_list args;
        va_start (args, format);
        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
        va_end (args);
    }
}


//----------------------------------------------------------------------
// Log only if all of the bits are set
//----------------------------------------------------------------------
void
Log::LogIf (uint32_t bits, const char *format, ...)
{
    if ((bits & m_options.GetAllFlagBits()) == bits)
    {
        va_list args;
        va_start (args, format);
        PrintfWithFlagsVarArg (0, format, args);
        va_end (args);
    }
}


//----------------------------------------------------------------------
// Printing of errors that are not fatal.
//----------------------------------------------------------------------
void
Log::Error (const char *format, ...)
{
    char *arg_msg = NULL;
    va_list args;
    va_start (args, format);
    ::vasprintf (&arg_msg, format, args);
    va_end (args);

    if (arg_msg != NULL)
    {
        PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
        free (arg_msg);
    }
}

//----------------------------------------------------------------------
// Printing of errors that ARE fatal. Exit with ERR exit code
// immediately.
//----------------------------------------------------------------------
void
Log::FatalError (int err, const char *format, ...)
{
    char *arg_msg = NULL;
    va_list args;
    va_start (args, format);
    ::vasprintf (&arg_msg, format, args);
    va_end (args);

    if (arg_msg != NULL)
    {
        PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
        ::free (arg_msg);
    }
    ::exit (err);
}


//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
//----------------------------------------------------------------------
void
Log::Verbose (const char *format, ...)
{
    if (m_options.IsSet(LLDB_LOG_OPTION_VERBOSE))
    {
        va_list args;
        va_start (args, format);
        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
        va_end (args);
    }
}

//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
//----------------------------------------------------------------------
void
Log::WarningVerbose (const char *format, ...)
{
    if (m_options.IsSet(LLDB_LOG_OPTION_VERBOSE))
    {
        char *arg_msg = NULL;
        va_list args;
        va_start (args, format);
        ::vasprintf (&arg_msg, format, args);
        va_end (args);

        if (arg_msg != NULL)
        {
            PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
            free (arg_msg);
        }
    }
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal.
//----------------------------------------------------------------------
void
Log::Warning (const char *format, ...)
{
    char *arg_msg = NULL;
    va_list args;
    va_start (args, format);
    ::vasprintf (&arg_msg, format, args);
    va_end (args);

    if (arg_msg != NULL)
    {
        PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
        free (arg_msg);
    }
}

typedef std::map <std::string, Log::Callbacks> CallbackMap;
typedef CallbackMap::iterator CallbackMapIter;

typedef std::map <ConstString, LogChannelSP> LogChannelMap;
typedef LogChannelMap::iterator LogChannelMapIter;


// Surround our callback map with a singleton function so we don't have any
// global initializers.
static CallbackMap &
GetCallbackMap ()
{
    static CallbackMap g_callback_map;
    return g_callback_map;
}

static LogChannelMap &
GetChannelMap ()
{
    static LogChannelMap g_channel_map;
    return g_channel_map;
}

void
Log::RegisterLogChannel (const char *channel, const Log::Callbacks &log_callbacks)
{
    GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
}

bool
Log::UnregisterLogChannel (const char *channel)
{
    return GetCallbackMap().erase(channel) != 0;
}

bool
Log::GetLogChannelCallbacks (const char *channel, Log::Callbacks &log_callbacks)
{
    CallbackMap &callback_map = GetCallbackMap ();
    CallbackMapIter pos = callback_map.find(channel);
    if (pos != callback_map.end())
    {
        log_callbacks = pos->second;
        return true;
    }
    ::bzero (&log_callbacks, sizeof(log_callbacks));
    return false;
}

void
Log::EnableAllLogChannels
(
    StreamSP &log_stream_sp,
    uint32_t log_options,
    Args &args,
    Stream *feedback_strm
)
{
    CallbackMap &callback_map = GetCallbackMap ();
    CallbackMapIter pos, end = callback_map.end();

    for (pos = callback_map.begin(); pos != end; ++pos)
        pos->second.enable (log_stream_sp, log_options, args, feedback_strm);

    LogChannelMap &channel_map = GetChannelMap ();
    LogChannelMapIter channel_pos, channel_end = channel_map.end();
    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
    {
        channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, args);
    }

}

void
Log::DisableAllLogChannels ()
{
    CallbackMap &callback_map = GetCallbackMap ();
    CallbackMapIter pos, end = callback_map.end();

    for (pos = callback_map.begin(); pos != end; ++pos)
        pos->second.disable ();

    LogChannelMap &channel_map = GetChannelMap ();
    LogChannelMapIter channel_pos, channel_end = channel_map.end();
    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
        channel_pos->second->Disable ();
}

void
Log::ListAllLogChannels (Stream *strm)
{
    CallbackMap &callback_map = GetCallbackMap ();
    LogChannelMap &channel_map = GetChannelMap ();

    if (callback_map.empty() && channel_map.empty())
    {
        strm->PutCString ("No logging channels are currently registered.\n");
        return;
    }

    CallbackMapIter pos, end = callback_map.end();
    for (pos = callback_map.begin(); pos != end; ++pos)
        pos->second.list_categories (strm);

    uint32_t idx = 0;
    const char *name;
    for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
    {
        LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
        if (log_channel_sp)
            log_channel_sp->ListCategories (strm);
    }
}

bool
Log::GetVerbose() const
{
    if (m_stream_sp)
        return m_stream_sp->GetVerbose();
    return false;
}

//------------------------------------------------------------------
// Returns true if the debug flag bit is set in this stream.
//------------------------------------------------------------------
bool
Log::GetDebug() const
{
    if (m_stream_sp)
        return m_stream_sp->GetDebug();
    return false;
}


LogChannelSP
LogChannel::FindPlugin (const char *plugin_name)
{
    LogChannelSP log_channel_sp;
    LogChannelMap &channel_map = GetChannelMap ();
    ConstString log_channel_name (plugin_name);
    LogChannelMapIter pos = channel_map.find (log_channel_name);
    if (pos == channel_map.end())
    {
        LogChannelCreateInstance create_callback  = PluginManager::GetLogChannelCreateCallbackForPluginName (plugin_name);
        if (create_callback)
        {
            log_channel_sp.reset(create_callback());
            if (log_channel_sp)
            {
                // Cache the one and only loaded instance of each log channel
                // plug-in after it has been loaded once.
                channel_map[log_channel_name] = log_channel_sp;
            }
        }
    }
    else
    {
        // We have already loaded an instance of this log channel class,
        // so just return the cached instance.
        log_channel_sp = pos->second;
    }
    return log_channel_sp;
}

LogChannel::LogChannel () :
    m_log_sp ()
{
}

LogChannel::~LogChannel ()
{
}

const char *
LogChannel::GetPluginSuffix ()
{
    return ".log-channel";
}


