/*
 * 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 "systemc/core/module.hh"

#include <cassert>

#include "base/logging.hh"
#include "systemc/ext/core/sc_export.hh"
#include "systemc/ext/core/sc_port.hh"
#include "systemc/ext/utils/sc_report_handler.hh"

namespace sc_gem5
{

namespace
{

std::list<Module *> _modules;
Module *_new_module;

} // anonymous namespace

Module::Module(const char *name) :
    _name(name), _sc_mod(nullptr), _obj(nullptr), _ended(false),
    _deprecatedConstructor(false)
{
    panic_if(_new_module, "Previous module not finished.\n");
    _new_module = this;
}

Module::~Module()
{
    // Aborted module construction?
    if (_new_module == this)
        _new_module = nullptr;

    // Attempt to pop now in case we're at the top of the stack, so that
    // a stale pointer to us isn't left floating around for somebody to trip
    // on.
    pop();

    allModules.remove(this);
}

void
Module::finish(Object *this_obj)
{
    assert(!_obj);
    _obj = this_obj;
    _modules.push_back(this);
    pushParentModule(this);
    try {
        _new_module = nullptr;
        // This is called from the constructor of this_obj, so it can't use
        // dynamic cast.
        sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj()));
        allModules.emplace_back(this);
    } catch (...) {
        popParentModule();
        throw;
    }
}

void
Module::pop()
{
    if (_modules.empty() || _modules.back() != this)
        return;

    panic_if(_new_module, "Pop with unfinished module.\n");

    _modules.pop_back();
    popParentModule();
}

void
Module::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies)
{
    panic_if(proxies.size() > ports.size(),
            "Trying to bind %d interfaces/ports to %d ports.\n",
            proxies.size(), ports.size());

    auto proxyIt = proxies.begin();
    auto portIt = ports.begin();
    for (; proxyIt != proxies.end(); proxyIt++, portIt++) {
        auto proxy = *proxyIt;
        auto port = *portIt;
        if (proxy->interface())
            port->vbind(*proxy->interface());
        else
            port->vbind(*proxy->port());
    }
}

void
Module::beforeEndOfElaboration()
{
    pushParentModule(this);
    try {
        _sc_mod->before_end_of_elaboration();
        for (auto e: exports)
            e->before_end_of_elaboration();
    } catch (...) {
        popParentModule();
        throw;
    }
    popParentModule();
}

void
Module::endOfElaboration()
{
    if (_deprecatedConstructor && !_ended) {
        std::string msg = csprintf("module '%s'", name());
        SC_REPORT_WARNING("(W509) module construction not properly completed: "
                "did you forget to add a sc_module_name parameter to "
                "your module constructor?", msg.c_str());
    }
    pushParentModule(this);
    try {
        _sc_mod->end_of_elaboration();
        for (auto e: exports)
            e->end_of_elaboration();
    } catch (...) {
        popParentModule();
        throw;
    }
    popParentModule();
}

void
Module::startOfSimulation()
{
    pushParentModule(this);
    try {
        _sc_mod->start_of_simulation();
        for (auto e: exports)
            e->start_of_simulation();
    } catch (...) {
        popParentModule();
        throw;
    }
    popParentModule();
}

void
Module::endOfSimulation()
{
    pushParentModule(this);
    try {
        _sc_mod->end_of_simulation();
        for (auto e: exports)
            e->end_of_simulation();
    } catch(...) {
        popParentModule();
        throw;
    }
    popParentModule();
}

Module *
currentModule()
{
    if (_modules.empty())
        return nullptr;
    return _modules.back();
}

Module *
newModuleChecked()
{
    if (!_new_module) {
        SC_REPORT_ERROR("(E533) module name stack is empty: "
                "did you forget to add a sc_module_name parameter to "
                "your module constructor?", nullptr);
    }
    return _new_module;
}

Module *
newModule()
{
    return _new_module;
}

std::list<Module *> allModules;

} // namespace sc_gem5
