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

#include "LogChannelDWARF.h"

#include "lldb/Interpreter/Args.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "SymbolFileDWARF.h"

using namespace lldb;
using namespace lldb_private;


// when the one and only logging channel is abled, then this will be non NULL.
static LogChannelDWARF* g_log_channel = NULL;

LogChannelDWARF::LogChannelDWARF () :
    LogChannel ()
{
}

LogChannelDWARF::~LogChannelDWARF ()
{
}


void
LogChannelDWARF::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   LogChannelDWARF::CreateInstance);
}

void
LogChannelDWARF::Terminate()
{
    PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
}

LogChannel*
LogChannelDWARF::CreateInstance ()
{
    return new LogChannelDWARF ();
}

lldb_private::ConstString
LogChannelDWARF::GetPluginNameStatic()
{
    return SymbolFileDWARF::GetPluginNameStatic();
}

const char *
LogChannelDWARF::GetPluginDescriptionStatic()
{
    return "DWARF log channel for debugging plug-in issues.";
}

lldb_private::ConstString
LogChannelDWARF::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
LogChannelDWARF::GetPluginVersion()
{
    return 1;
}


void
LogChannelDWARF::Delete ()
{
    g_log_channel = NULL;
}


void
LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
{
    if (m_log_ap.get() == NULL)
        return;

    uint32_t flag_bits = m_log_ap->GetMask().Get();
    for (size_t i = 0; categories[i] != NULL; ++i)
    {
         const char *arg = categories[i];

        if      (::strcasecmp (arg, "all")        == 0) flag_bits &= ~DWARF_LOG_ALL;
        else if (::strcasecmp (arg, "info")       == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO;
        else if (::strcasecmp (arg, "line")       == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE;
        else if (::strcasecmp (arg, "pubnames")   == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
        else if (::strcasecmp (arg, "pubtypes")   == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
        else if (::strcasecmp (arg, "aranges")    == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
        else if (::strcasecmp (arg, "lookups")    == 0) flag_bits &= ~DWARF_LOG_LOOKUPS;
        else if (::strcasecmp (arg, "map")        == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP;
        else if (::strcasecmp (arg, "default")    == 0) flag_bits &= ~DWARF_LOG_DEFAULT;
        else if (::strncasecmp(arg, "comp", 4)    == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
        else
        {
            feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
            ListCategories (feedback_strm);
        }
   }
    
    if (flag_bits == 0)
        Delete ();
    else
        m_log_ap->GetMask().Reset (flag_bits);

    return;
}

bool
LogChannelDWARF::Enable
(
    StreamSP &log_stream_sp,
    uint32_t log_options,
    Stream *feedback_strm,  // Feedback stream for argument errors etc
    const char **categories  // The categories to enable within this logging stream, if empty, enable default set
)
{
    Delete ();

    if (m_log_ap)
        m_log_ap->SetStream(log_stream_sp);
    else
        m_log_ap.reset(new Log (log_stream_sp));
    
    g_log_channel = this;
    uint32_t flag_bits = 0;
    bool got_unknown_category = false;
    for (size_t i = 0; categories[i] != NULL; ++i)
    {
        const char *arg = categories[i];

        if      (::strcasecmp (arg, "all")        == 0) flag_bits |= DWARF_LOG_ALL;
        else if (::strcasecmp (arg, "info")       == 0) flag_bits |= DWARF_LOG_DEBUG_INFO;
        else if (::strcasecmp (arg, "line")       == 0) flag_bits |= DWARF_LOG_DEBUG_LINE;
        else if (::strcasecmp (arg, "pubnames")   == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
        else if (::strcasecmp (arg, "pubtypes")   == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
        else if (::strcasecmp (arg, "aranges")    == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES;
        else if (::strcasecmp (arg, "lookups")    == 0) flag_bits |= DWARF_LOG_LOOKUPS;
        else if (::strcasecmp (arg, "map")        == 0) flag_bits |= DWARF_LOG_DEBUG_MAP;
        else if (::strcasecmp (arg, "default")    == 0) flag_bits |= DWARF_LOG_DEFAULT;
        else if (::strncasecmp(arg, "comp", 4)    == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION;
        else
        {
            feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
            if (got_unknown_category == false)
            {
                got_unknown_category = true;
                ListCategories (feedback_strm);
            }
        }
    }
    if (flag_bits == 0)
        flag_bits = DWARF_LOG_DEFAULT;
    m_log_ap->GetMask().Reset(flag_bits);
    m_log_ap->GetOptions().Reset(log_options);
    return m_log_ap.get() != NULL;
}

void
LogChannelDWARF::ListCategories (Stream *strm)
{
    strm->Printf ("Logging categories for '%s':\n"
                  "  all - turn on all available logging categories\n"
                  "  info - log the parsing if .debug_info\n"
                  "  line - log the parsing if .debug_line\n"
                  "  pubnames - log the parsing if .debug_pubnames\n"
                  "  pubtypes - log the parsing if .debug_pubtypes\n"
                  "  lookups - log any lookups that happen by name, regex, or address\n"
                  "  completion - log struct/unions/class type completions\n"
                  "  map - log insertions of object files into DWARF debug maps\n",
                  SymbolFileDWARF::GetPluginNameStatic().GetCString());
}

Log *
LogChannelDWARF::GetLog ()
{
    if (g_log_channel)
        return g_log_channel->m_log_ap.get();

    return NULL;
}

Log *
LogChannelDWARF::GetLogIfAll (uint32_t mask)
{
    if (g_log_channel && g_log_channel->m_log_ap.get())
    {
        if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
            return g_log_channel->m_log_ap.get();
    }
    return NULL;
}

Log *
LogChannelDWARF::GetLogIfAny (uint32_t mask)
{
    if (g_log_channel && g_log_channel->m_log_ap.get())
    {
        if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
            return g_log_channel->m_log_ap.get();
    }
    return NULL;
}

void
LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
{
    if (g_log_channel)
    {
        Log *log = g_log_channel->m_log_ap.get();
        if (log && log->GetMask().AnySet(mask))
        {
            va_list args;
            va_start (args, format);
            log->VAPrintf (format, args);
            va_end (args);
        }
    }
}
