/*
 * 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_PROCESS_HH__
#define __SYSTEMC_CORE_PROCESS_HH__

#include <functional>
#include <memory>
#include <vector>

#include "base/fiber.hh"
#include "sim/eventq.hh"
#include "systemc/core/bindinfo.hh"
#include "systemc/core/list.hh"
#include "systemc/core/object.hh"
#include "systemc/core/sched_event.hh"
#include "systemc/ext/core/sc_event.hh"
#include "systemc/ext/core/sc_export.hh"
#include "systemc/ext/core/sc_interface.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_port.hh"
#include "systemc/ext/core/sc_process_handle.hh"
#include "systemc/ext/utils/sc_report.hh"

namespace sc_gem5
{

class Sensitivity
{
  protected:
    Process *process;

  public:
    Sensitivity(Process *p) : process(p) {}
    virtual ~Sensitivity() {}

    virtual void notifyWork(Event *e);
    void notify(Event *e);
    void notify() { notify(nullptr); }

    const std::string name();
};

class SensitivityTimeout : virtual public Sensitivity
{
  private:
    void timeout();
    ScEvent timeoutEvent;

  public:
    SensitivityTimeout(Process *p, ::sc_core::sc_time t);
    ~SensitivityTimeout();
};

class SensitivityEvent : virtual public Sensitivity
{
  private:
    const ::sc_core::sc_event *event;

  public:
    SensitivityEvent(Process *p, const ::sc_core::sc_event *e);
    ~SensitivityEvent();
};

//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
//recreated. That works for dynamic sensitivities, but not for static.
//Fortunately processes can't be statically sensitive to sc_event_and_lists.
class SensitivityEventAndList : virtual public Sensitivity
{
  private:
    const ::sc_core::sc_event_and_list *list;
    int count;

  public:
    SensitivityEventAndList(
            Process *p, const ::sc_core::sc_event_and_list *list);
    ~SensitivityEventAndList();

    void notifyWork(Event *e) override;
};

class SensitivityEventOrList : virtual public Sensitivity
{
  private:
    const ::sc_core::sc_event_or_list *list;

  public:
    SensitivityEventOrList(
            Process *p, const ::sc_core::sc_event_or_list *list);
    ~SensitivityEventOrList();
};

// Combined sensitivities. These trigger when any of their parts do.

class SensitivityTimeoutAndEvent :
    public SensitivityTimeout, public SensitivityEvent
{
  public:
    SensitivityTimeoutAndEvent(
            Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) :
        Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e)
    {}
};

class SensitivityTimeoutAndEventAndList :
    public SensitivityTimeout, public SensitivityEventAndList
{
  public:
    SensitivityTimeoutAndEventAndList(
            Process *p, ::sc_core::sc_time t,
            const ::sc_core::sc_event_and_list *eal) :
        Sensitivity(p), SensitivityTimeout(p, t),
        SensitivityEventAndList(p, eal)
    {}

    void notifyWork(Event *e) override;
};

class SensitivityTimeoutAndEventOrList :
    public SensitivityTimeout, public SensitivityEventOrList
{
  public:
    SensitivityTimeoutAndEventOrList(
            Process *p, ::sc_core::sc_time t,
            const ::sc_core::sc_event_or_list *eol) :
        Sensitivity(p), SensitivityTimeout(p, t),
        SensitivityEventOrList(p, eol)
    {}
};

typedef std::vector<Sensitivity *> Sensitivities;


/*
 * Pending sensitivities. These are records of sensitivities to install later,
 * once all the information to configure them is available.
 */

class PendingSensitivity
{
  protected:
    Process *process;

  public:
    virtual void finalize(Sensitivities &s) = 0;
    PendingSensitivity(Process *p) : process(p) {}
    virtual ~PendingSensitivity() {}
};

class PendingSensitivityEvent : public PendingSensitivity
{
  private:
    const sc_core::sc_event *event;

  public:
    PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) :
        PendingSensitivity(p), event(e) {}

    void
    finalize(Sensitivities &s) override
    {
        s.push_back(new SensitivityEvent(process, event));
    }
};

class PendingSensitivityInterface : public PendingSensitivity
{
  private:
    const sc_core::sc_interface *interface;

  public:
    PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) :
        PendingSensitivity(p), interface(i)
    {}

    void
    finalize(Sensitivities &s) override
    {
        s.push_back(new SensitivityEvent(process,
                                         &interface->default_event()));
    }
};

class PendingSensitivityPort : public PendingSensitivity
{
  private:
    const sc_core::sc_port_base *port;

  public:
    PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
        PendingSensitivity(p), port(pb)
    {}

    void
    finalize(Sensitivities &s) override
    {
        for (int i = 0; i < port->size(); i++) {
            const ::sc_core::sc_event *e =
                &port->_gem5Interface(i)->default_event();
            s.push_back(new SensitivityEvent(process, e));
        }
    }
};

class PendingSensitivityExport : public PendingSensitivity
{
  private:
    const sc_core::sc_export_base *exp;

  public:
    PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) :
        PendingSensitivity(p), exp(exp)
    {}

    void
    finalize(Sensitivities &s) override
    {
        s.push_back(new SensitivityEvent(process,
                    &exp->get_interface()->default_event()));
    }
};

class PendingSensitivityFinder : public PendingSensitivity
{
  private:
    const sc_core::sc_event_finder *finder;

  public:
    PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
        PendingSensitivity(p), finder(f)
    {}

    void
    finalize(Sensitivities &s) override
    {
        s.push_back(new SensitivityEvent(process, &finder->find_event()));
    }
};

typedef std::vector<PendingSensitivity *> PendingSensitivities;


class Process : public ::sc_core::sc_object, public ListNode
{
  public:
    virtual ::sc_core::sc_curr_proc_kind procKind() const = 0;
    bool needsStart() const { return _needsStart; }
    bool dynamic() const { return _dynamic; }
    bool isUnwinding() const { return _isUnwinding; }
    void isUnwinding(bool v) { _isUnwinding = v; }
    bool terminated() const { return _terminated; }

    void forEachKid(const std::function<void(Process *)> &work);

    bool suspended() const { return _suspended; }
    bool disabled() const { return _disabled; }

    void suspend(bool inc_kids);
    void resume(bool inc_kids);
    void disable(bool inc_kids);
    void enable(bool inc_kids);

    void kill(bool inc_kids);
    void reset(bool inc_kids);
    virtual void throw_it(ExceptionWrapperBase &exc, bool inc_kids);

    void injectException(ExceptionWrapperBase &exc);
    ExceptionWrapperBase *excWrapper;

    void syncResetOn(bool inc_kids);
    void syncResetOff(bool inc_kids);

    void incref() { refCount++; }
    void decref() { refCount--; }

    const ::sc_core::sc_event &resetEvent() { return _resetEvent; }
    const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; }

    // This should only be called before initialization.
    void dontInitialize();

    void setStackSize(size_t size) { stackSize = size; }

    void finalize();

    void run();

    void addStatic(PendingSensitivity *);
    void setDynamic(Sensitivity *);

    void satisfySensitivity(Sensitivity *);

    void ready();

    virtual Fiber *fiber() { return Fiber::primaryFiber(); }

    static Process *newest() { return _newest; }

    void lastReport(::sc_core::sc_report *report);
    ::sc_core::sc_report *lastReport() const;

  protected:
    Process(const char *name, ProcessFuncWrapper *func, bool _dynamic);

    static Process *_newest;

    virtual ~Process()
    {
        popListNode();
        delete func;
        for (auto s: staticSensitivities)
            delete s;
    }

    ::sc_core::sc_event _resetEvent;
    ::sc_core::sc_event _terminatedEvent;

    ProcessFuncWrapper *func;
    sc_core::sc_curr_proc_kind _procKind;
    bool _needsStart;
    bool _dynamic;
    bool _isUnwinding;
    bool _terminated;

    void terminate();

    bool _suspended;
    bool _suspendedReady;
    bool _disabled;

    bool _syncReset;

    int refCount;

    size_t stackSize;

    Sensitivities staticSensitivities;
    PendingSensitivities pendingStaticSensitivities;

    Sensitivity *dynamicSensitivity;

    std::unique_ptr<::sc_core::sc_report> _lastReport;
};

inline void
Sensitivity::notifyWork(Event *e)
{
    process->satisfySensitivity(this);
}

inline void
Sensitivity::notify(Event *e)
{
    if (!process->disabled())
        notifyWork(e);
}

inline const std::string
Sensitivity::name()
{
    return std::string(process->name()) + ".timeout";
}

} // namespace sc_gem5

#endif  //__SYSTEMC_CORE_PROCESS_HH__
