/*
 * 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_CORE_EVENT_HH__
#define __SYSTEMC_CORE_EVENT_HH__

#include <list>
#include <string>
#include <vector>

#include "sim/eventq.hh"
#include "systemc/core/list.hh"
#include "systemc/core/object.hh"
#include "systemc/core/process.hh"
#include "systemc/core/sched_event.hh"
#include "systemc/core/sensitivity.hh"
#include "systemc/ext/core/sc_prim.hh"
#include "systemc/ext/core/sc_time.hh"

namespace sc_core
{

class sc_event;

} // namespace sc_core

namespace sc_gem5
{

typedef std::vector<sc_core::sc_event *> Events;

class Sensitivity;

class Event
{
  public:
    Event(sc_core::sc_event *_sc_event, bool internal=false);
    Event(sc_core::sc_event *_sc_event, const char *_basename,
            bool internal=false);

    ~Event();

    sc_core::sc_event *sc_event() { return _sc_event; }

    const std::string &name() const;
    const std::string &basename() const;
    bool inHierarchy() const;
    sc_core::sc_object *getParentObject() const;

    void notify(StaticSensitivities &senses);
    void notify(DynamicSensitivities &senses);

    void notify();
    void notify(const sc_core::sc_time &t);
    void
    notify(double d, sc_core::sc_time_unit &u)
    {
        notify(sc_core::sc_time(d, u));
    }
    void notifyDelayed(const sc_core::sc_time &t);
    void cancel();

    bool triggered() const;
    uint64_t triggeredStamp() const { return _triggeredStamp; }

    static Event *
    getFromScEvent(sc_core::sc_event *e)
    {
        return e->_gem5_event;
    }

    static const Event *
    getFromScEvent(const sc_core::sc_event *e)
    {
        return e->_gem5_event;
    }

    void
    addSensitivity(StaticSensitivity *s) const
    {
        // Insert static sensitivities in reverse order to match Accellera's
        // implementation.
        auto &senses = s->ofMethod() ? staticSenseMethod : staticSenseThread;
        senses.insert(senses.begin(), s);
    }
    void
    delSensitivity(StaticSensitivity *s) const
    {
        auto &senses = s->ofMethod() ? staticSenseMethod : staticSenseThread;
        for (auto &t: senses) {
            if (t == s) {
                t = senses.back();
                senses.pop_back();
                break;
            }
        }
    }
    void
    addSensitivity(DynamicSensitivity *s) const
    {
        auto &senses = s->ofMethod() ? dynamicSenseMethod : dynamicSenseThread;
        senses.push_back(s);
    }
    void
    delSensitivity(DynamicSensitivity *s) const
    {
        auto &senses = s->ofMethod() ? dynamicSenseMethod : dynamicSenseThread;
        for (auto &t: senses) {
            if (t == s) {
                t = senses.back();
                senses.pop_back();
                break;
            }
        }
    }

    void clearParent();

  private:
    sc_core::sc_event *_sc_event;

    std::string _basename;
    std::string _name;
    bool _inHierarchy;

    sc_core::sc_object *parent;

    ScEvent delayedNotify;
    mutable uint64_t _triggeredStamp;

    mutable StaticSensitivities staticSenseMethod;
    mutable StaticSensitivities staticSenseThread;
    mutable DynamicSensitivities dynamicSenseMethod;
    mutable DynamicSensitivities dynamicSenseThread;
};

extern Events topLevelEvents;
extern Events allEvents;

EventsIt findEvent(const std::string &name);

} // namespace sc_gem5

#endif  //__SYSTEMC_CORE_EVENT_HH__
