/*
 * 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
 */

#ifndef __SYSTEMC_UTILS_REPORT_HH__
#define __SYSTEMC_UTILS_REPORT_HH__

#include <initializer_list>
#include <map>
#include <memory>
#include <string>
#include <utility>

#include "systemc/ext/utils/sc_report.hh"
#include "systemc/ext/utils/sc_report_handler.hh"

namespace sc_gem5
{

struct ReportMsgInfo
{
    explicit ReportMsgInfo() :
        actions(sc_core::SC_UNSPECIFIED), count(0), limit(-1),
        sevActions{ sc_core::SC_UNSPECIFIED, sc_core::SC_UNSPECIFIED,
                sc_core::SC_UNSPECIFIED, sc_core::SC_UNSPECIFIED },
        sevCounts{0, 0, 0, 0}, sevLimits{-1, -1, -1, -1}, id(-1)
    {}

    void
    checkLimits(sc_core::sc_severity severity, sc_core::sc_actions &actions)
    {
        int sevLimit = sevLimits[severity];
        int sevCount = sevCounts[severity];
        if ((limit != -1 && limit >= count) ||
                (sevLimit != 1 && sevLimit >= sevCount)) {
            actions |= sc_core::SC_STOP;
        }
    }

    sc_core::sc_actions actions;
    int count;
    int limit;

    sc_core::sc_actions sevActions[sc_core::SC_MAX_SEVERITY];
    int sevCounts[sc_core::SC_MAX_SEVERITY];
    int sevLimits[sc_core::SC_MAX_SEVERITY];

    int id;
};

struct ReportSevInfo
{
    explicit ReportSevInfo(sc_core::sc_actions actions) :
        actions(actions), count(0), limit(-1)
    {}

    void
    checkLimit(sc_core::sc_actions &actions)
    {
        if (limit != -1 && limit >= count)
            actions |= sc_core::SC_STOP;
    }

    sc_core::sc_actions actions;
    int count;
    int limit;
};

extern const char *reportSeverityNames[sc_core::SC_MAX_SEVERITY];
extern ReportSevInfo reportSevInfos[sc_core::SC_MAX_SEVERITY];

std::map<std::string, ReportMsgInfo> &reportMsgInfoMap();
std::map<int, std::string> &reportIdToMsgMap();

extern int reportVerbosityLevel;

extern sc_core::sc_actions reportSuppressedActions;
extern sc_core::sc_actions reportForcedActions;
extern sc_core::sc_actions reportCatchActions;

extern sc_core::sc_report_handler_proc reportHandlerProc;

extern std::unique_ptr<sc_core::sc_report> globalReportCache;

extern bool reportWarningsAsErrors;

struct DefaultReportMessages
{
  public:
    DefaultReportMessages(std::initializer_list<std::pair<int, const char *>>);
};

} // namespace sc_gem5

#endif // __SYSTEMC_UTILS_REPORT_HH__
