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

#include "ProcessWindowsLog.h"

#include <mutex>

#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/Args.h"
#include "llvm/Support/ManagedStatic.h"

#include "ProcessWindows.h"

using namespace lldb;
using namespace lldb_private;


// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_log_sp the first time this function is
// called.
static bool g_log_enabled = false;
static Log * g_log = nullptr;

static llvm::ManagedStatic<std::once_flag> g_once_flag;

void
ProcessWindowsLog::Initialize()
{
    static ConstString g_name("windows");

    std::call_once(*g_once_flag, [](){
        Log::Callbacks log_callbacks = {
            DisableLog,
            EnableLog,
            ListLogCategories
        };

        Log::RegisterLogChannel(g_name, log_callbacks);
        RegisterPluginName(g_name);
    });
}

void
ProcessWindowsLog::Terminate()
{
}

Log *
ProcessWindowsLog::GetLog()
{
    return (g_log_enabled) ? g_log : nullptr;
}

bool
ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req)
{
    Log *log = GetLog();
    if (!log)
        return false;

    uint32_t log_mask = log->GetMask().Get();
    if (req == LogMaskReq::All)
        return ((log_mask & mask) == mask);
    else
        return (log_mask & mask);
}

static uint32_t
GetFlagBits(const char *arg)
{
    if      (::strcasecmp(arg, "all") == 0 ) return WINDOWS_LOG_ALL;
    else if (::strcasecmp(arg, "break") == 0 ) return WINDOWS_LOG_BREAKPOINTS;
    else if (::strcasecmp(arg, "event") == 0 ) return WINDOWS_LOG_EVENT;
    else if (::strcasecmp(arg, "exception") == 0 ) return WINDOWS_LOG_EXCEPTION;
    else if (::strcasecmp(arg, "memory") == 0 ) return WINDOWS_LOG_MEMORY;
    else if (::strcasecmp(arg, "process") == 0 ) return WINDOWS_LOG_PROCESS;
    else if (::strcasecmp(arg, "registers") == 0 ) return WINDOWS_LOG_REGISTERS;
    else if (::strcasecmp(arg, "step") == 0 ) return WINDOWS_LOG_STEP;
    else if (::strcasecmp(arg, "thread") == 0 ) return WINDOWS_LOG_THREAD;
    else if (::strcasecmp(arg, "verbose") == 0 ) return WINDOWS_LOG_VERBOSE;
    return 0;
}

void
ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm)
{
    Log *log (GetLog());
    if (log)
    {
        uint32_t flag_bits = 0;

        flag_bits = log->GetMask().Get();
        for (; args[0]; args++)
        {
            const char *arg = args[0];
            uint32_t bits = GetFlagBits(arg);

            if (bits)
            {
                flag_bits &= ~bits;
            }
            else
            {
                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
                ListLogCategories(feedback_strm);
            }
        }

        log->GetMask().Reset(flag_bits);
        if (flag_bits == 0)
            g_log_enabled = false;
    }

    return;
}

Log *
ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
{
    // Try see if there already is a log - that way we can reuse its settings.
    // We could reuse the log in toto, but we don't know that the stream is the same.
    uint32_t flag_bits = 0;
    if (g_log)
        flag_bits = g_log->GetMask().Get();

    // Now make a new log with this stream if one was provided
    if (log_stream_sp)
    {
        if (g_log)
            g_log->SetStream(log_stream_sp);
        else
            g_log = new Log(log_stream_sp);
    }

    if (g_log)
    {
        bool got_unknown_category = false;
        for (; args[0]; args++)
        {
            const char *arg = args[0];
            uint32_t bits = GetFlagBits(arg);

            if (bits)
            {
                flag_bits |= bits;
            }
            else
            {
                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
                if (got_unknown_category == false)
                {
                    got_unknown_category = true;
                    ListLogCategories (feedback_strm);
                }
            }
        }
        if (flag_bits == 0)
            flag_bits = WINDOWS_LOG_ALL;
        g_log->GetMask().Reset(flag_bits);
        g_log->GetOptions().Reset(log_options);
        g_log_enabled = true;
    }
    return g_log;
}

void
ProcessWindowsLog::ListLogCategories(Stream *strm)
{
    strm->Printf("Logging categories for '%s':\n"
                 "  all - turn on all available logging categories\n"
                 "  break - log breakpoints\n"
                 "  event - log low level debugger events\n"
                 "  exception - log exception information\n"
                 "  memory - log memory reads and writes\n"
                 "  process - log process events and activities\n"
                 "  registers - log register read/writes\n"
                 "  thread - log thread events and activities\n"
                 "  step - log step related activities\n"
                 "  verbose - enable verbose logging\n",
                 ProcessWindowsLog::m_pluginname);
}

const char *ProcessWindowsLog::m_pluginname = "";
