/*
 * Copyright (c) 2014, 2019 ARM Limited
 * All rights reserved
 *
 * Copyright (c) 2001-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "base/trace.hh"

#include <cctype>
#include <fstream>
#include <iostream>
#include <sstream>

#include "base/atomicio.hh"
#include "base/logging.hh"
#include "base/str.hh"
#include "debug/FmtFlag.hh"
#include "debug/FmtStackTrace.hh"
#include "debug/FmtTicksOff.hh"
#include "sim/backtrace.hh"

const std::string &
name()
{
    static const std::string default_name("global");

    return default_name;
}

namespace gem5
{

namespace trace
{

// This variable holds the output logger for debug information.  Other
// than setting up/redirecting this logger, do *NOT* reference this
// directly

Logger *debug_logger = NULL;

Logger *
getDebugLogger()
{
    /* Set a default logger to cerr when no other logger is set */
    if (!debug_logger)
        debug_logger = new OstreamLogger(std::cerr);

    return debug_logger;
}

std::ostream &
output()
{
    return getDebugLogger()->getOstream();
}

void
setDebugLogger(Logger *logger)
{
    if (!logger)
        warn("Trying to set debug logger to NULL\n");
    else
        debug_logger = logger;
}

void
enable()
{
    debug::Flag::globalEnable();
}

void
disable()
{
    debug::Flag::globalDisable();
}

ObjectMatch ignore;


void
Logger::dump(Tick when, const std::string &name,
         const void *d, int len, const std::string &flag)
{
    if (!isEnabled(name))
        return;

    const char *data = static_cast<const char *>(d);
    int c, i, j;

    for (i = 0; i < len; i += 16) {
        std::ostringstream line;

        ccprintf(line, "%08x  ", i);
        c = len - i;
        if (c > 16) c = 16;

        for (j = 0; j < c; j++) {
            ccprintf(line, "%02x ", data[i + j] & 0xff);
            if ((j & 0xf) == 7 && j > 0)
                ccprintf(line, " ");
        }

        for (; j < 16; j++)
            ccprintf(line, "   ");
        ccprintf(line, "  ");

        for (j = 0; j < c; j++) {
            int ch = data[i + j] & 0x7f;
            ccprintf(line, "%c", (char)(isprint(ch) ? ch : ' '));
        }

        ccprintf(line, "\n");
        logMessage(when, name, flag, line.str());

        if (c < 16)
            break;
    }
}

void
OstreamLogger::logMessage(Tick when, const std::string &name,
        const std::string &flag, const std::string &message)
{
    if (!isEnabled(name))
        return;

    if (!debug::FmtTicksOff && (when != MaxTick))
        ccprintf(stream, "%7d: ", when);

    if (debug::FmtFlag && !flag.empty())
        stream << flag << ": ";

    if (!name.empty())
        stream << name << ": ";

    stream << message;
    stream.flush();

    if (debug::FmtStackTrace) {
        print_backtrace();
        STATIC_ERR("\n");
    }
}

} // namespace trace
} // namespace gem5
