/*
 * Copyright 2018 Google, Inc.
 *
 * 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.
 *
 * Authors: Gabe Black
 */

#include <fstream>
#include <map>
#include <sstream>
#include <string>

#include "base/logging.hh"
#include "systemc/core/process.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/messages.hh"
#include "systemc/ext/utils/sc_report_handler.hh"
#include "systemc/utils/report.hh"

namespace sc_core
{

namespace
{

std::unique_ptr<std::string> logFileName;
std::unique_ptr<std::ofstream> logFile;

} // anonymous namespace

void
sc_report_handler::report(sc_severity severity, const char *msg_type,
                          const char *msg, const char *file, int line)
{
    report(severity, msg_type, msg, SC_MEDIUM, file, line);
}

void
sc_report_handler::report(sc_severity severity, const char *msg_type,
                          const char *msg, int verbosity, const char *file,
                          int line)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    if (severity == SC_INFO && verbosity > sc_gem5::reportVerbosityLevel)
        return;

    sc_gem5::ReportSevInfo &sevInfo = sc_gem5::reportSevInfos[severity];
    sc_gem5::ReportMsgInfo &msgInfo = sc_gem5::reportMsgInfoMap[msg_type];

    sevInfo.count++;
    msgInfo.count++;
    msgInfo.sevCounts[severity]++;

    sc_actions actions = SC_UNSPECIFIED;
    if (msgInfo.sevActions[severity] != SC_UNSPECIFIED)
        actions = msgInfo.sevActions[severity];
    else if (msgInfo.actions != SC_UNSPECIFIED)
        actions = msgInfo.actions;
    else if (sevInfo.actions != SC_UNSPECIFIED)
        actions = sevInfo.actions;

    actions &= ~sc_gem5::reportSuppressedActions;
    actions |= sc_gem5::reportForcedActions;

    msgInfo.checkLimits(severity, actions);
    sevInfo.checkLimit(actions);

    ::sc_gem5::Process *current = ::sc_gem5::scheduler.current();
    sc_report report(severity, msg_type, msg, verbosity, file, line,
            sc_time::from_value(::sc_gem5::scheduler.getCurTick()),
            current ? current->name() : nullptr, msgInfo.id);

    if (actions & SC_CACHE_REPORT) {
        if (current) {
            current->lastReport(&report);
        } else {
            sc_gem5::globalReportCache =
                std::unique_ptr<sc_report>(new sc_report(report));
        }
    }

    sc_gem5::reportHandlerProc(report, actions);
}

void
sc_report_handler::report(sc_severity severity, int id, const char *msg,
                          const char *file, int line)
{
    std::string &msg_type = sc_gem5::reportIdToMsgMap[id];

    if (sc_gem5::reportWarningsAsErrors && severity == SC_WARNING)
        severity = SC_ERROR;

    report(severity, msg_type.c_str(), msg, file, line);
}

sc_actions
sc_report_handler::set_actions(sc_severity severity, sc_actions actions)
{
    sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity];
    sc_actions previous = info.actions;
    info.actions = actions;
    return previous;
}

sc_actions
sc_report_handler::set_actions(const char *msg_type, sc_actions actions)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type];
    sc_actions previous = info.actions;
    info.actions = actions;
    return previous;
}

sc_actions
sc_report_handler::set_actions(
        const char *msg_type, sc_severity severity, sc_actions actions)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type];
    sc_actions previous = info.sevActions[severity];
    info.sevActions[severity] = actions;
    return previous;
}

int
sc_report_handler::stop_after(sc_severity severity, int limit)
{
    sc_gem5::ReportSevInfo &info = sc_gem5::reportSevInfos[severity];
    int previous = info.limit;
    info.limit = limit;
    return previous;
}

int
sc_report_handler::stop_after(const char *msg_type, int limit)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type];
    int previous = info.limit;
    info.limit = limit;
    return previous;
}

int
sc_report_handler::stop_after(
        const char *msg_type, sc_severity severity, int limit)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    sc_gem5::ReportMsgInfo &info = sc_gem5::reportMsgInfoMap[msg_type];
    int previous = info.sevLimits[severity];
    info.sevLimits[severity] = limit;
    return previous;
}

int
sc_report_handler::get_count(sc_severity severity)
{
    return sc_gem5::reportSevInfos[severity].count;
}

int
sc_report_handler::get_count(const char *msg_type)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    return sc_gem5::reportMsgInfoMap[msg_type].count;
}

int
sc_report_handler::get_count(const char *msg_type, sc_severity severity)
{
    if (!msg_type)
        msg_type = SC_ID_UNKNOWN_ERROR_;

    return sc_gem5::reportMsgInfoMap[msg_type].sevCounts[severity];
}

int
sc_report_handler::set_verbosity_level(int vl)
{
    int previous = sc_gem5::reportVerbosityLevel;
    sc_gem5::reportVerbosityLevel = vl;
    return previous;
}

int
sc_report_handler::get_verbosity_level()
{
    return sc_gem5::reportVerbosityLevel;
}


sc_actions
sc_report_handler::suppress(sc_actions actions)
{
    sc_actions previous = sc_gem5::reportSuppressedActions;
    sc_gem5::reportSuppressedActions = actions;
    return previous;
}

sc_actions
sc_report_handler::suppress()
{
    return suppress(SC_UNSPECIFIED);
}

sc_actions
sc_report_handler::force(sc_actions actions)
{
    sc_actions previous = sc_gem5::reportForcedActions;
    sc_gem5::reportForcedActions = actions;
    return previous;
}

sc_actions
sc_report_handler::force()
{
    return force(SC_UNSPECIFIED);
}


sc_actions
sc_report_handler::set_catch_actions(sc_actions actions)
{
    sc_actions previous = sc_gem5::reportCatchActions;
    sc_gem5::reportCatchActions = actions;
    return previous;
}

sc_actions
sc_report_handler::get_catch_actions()
{
    return sc_gem5::reportCatchActions;
}


void
sc_report_handler::set_handler(sc_report_handler_proc proc)
{
    sc_gem5::reportHandlerProc = proc;
}

void
sc_report_handler::default_handler(
        const sc_report &report, const sc_actions &actions)
{
    if (actions & SC_DISPLAY)
        cprintf("\n%s\n", sc_report_compose_message(report));

    if ((actions & SC_LOG) && logFile) {
        ccprintf(*logFile, "%s: %s\n", report.get_time().to_string(),
                 sc_report_compose_message(report));
    }
    if (actions & SC_STOP) {
        sc_stop_here(report.get_msg_type(), report.get_severity());
        sc_stop();
    }
    if (actions & SC_INTERRUPT)
        sc_interrupt_here(report.get_msg_type(), report.get_severity());
    if (actions & SC_ABORT)
        sc_abort();
    if (actions & SC_THROW) {
        ::sc_gem5::Process *current = ::sc_gem5::scheduler.current();
        if (current)
            current->isUnwinding(false);
        throw report;
    }
}

sc_actions
sc_report_handler::get_new_action_id()
{
    static sc_actions maxAction = SC_ABORT;
    maxAction = maxAction << 1;
    return maxAction;
}

sc_report *
sc_report_handler::get_cached_report()
{
    ::sc_gem5::Process *current = ::sc_gem5::scheduler.current();
    if (current)
        return current->lastReport();
    return ::sc_gem5::globalReportCache.get();
}

void
sc_report_handler::clear_cached_report()
{
    ::sc_gem5::Process *current = ::sc_gem5::scheduler.current();
    if (current) {
        current->lastReport(nullptr);
    } else {
        ::sc_gem5::globalReportCache = nullptr;
    }
}

bool
sc_report_handler::set_log_file_name(const char *new_name)
{
    if (!new_name) {
        logFile = nullptr;
        logFileName = nullptr;
        return false;
    } else {
        if (logFileName)
            return false;
        logFileName = std::unique_ptr<std::string>(new std::string(new_name));
        logFile = std::unique_ptr<std::ofstream>(new std::ofstream(new_name));
        return true;
    }
}

const char *
sc_report_handler::get_log_file_name()
{
    if (!logFileName)
        return nullptr;
    else
        return logFileName->c_str();
}

void
sc_interrupt_here(const char *msg_type, sc_severity)
{
    // Purposefully empty, for setting breakpoints supposedly.
}

void
sc_stop_here(const char *msg_type, sc_severity)
{
    // Purposefully empty, for setting breakpoints supposedly.
}

const std::string
sc_report_compose_message(const sc_report &report)
{
    std::ostringstream str;

    const char *sevName = sc_gem5::reportSeverityNames[report.get_severity()];
    int id = report.get_id();

    str << sevName << ": ";
    if (id >= 0) {
        ccprintf(str, "(%c%d) ", sevName[0], id);
    }
    str << report.get_msg_type();

    const char *msg = report.get_msg();
    if (msg && msg[0])
        str << ": " << msg;

    if (report.get_severity() > SC_INFO) {
        ccprintf(str, "\nIn file: %s:%d", report.get_file_name(),
                 report.get_line_number());

        ::sc_gem5::Process *current = ::sc_gem5::scheduler.current();
        const char *name = report.get_process_name();
        if (current && sc_is_running() && name) {
            ccprintf(str, "\nIn process: %s @ %s", name,
                    report.get_time().to_string());
        }
    }

    return str.str();
}

bool
sc_report_close_default_log()
{
    if (logFile) {
        logFile = nullptr;
        logFileName = nullptr;
        return false;
    }
    return true;
}

} // namespace sc_core
