/*
 * 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 "systemc/core/list.hh"
#include "systemc/core/module.hh"
#include "systemc/core/object.hh"
#include "systemc/core/sched_event.hh"
#include "systemc/core/sensitivity.hh"
#include "systemc/ext/channel/sc_signal_in_if.hh"
#include "systemc/ext/core/sc_event.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_process_handle.hh"

namespace sc_core
{

class sc_join;

} // namespace sc_core

namespace sc_gem5
{

class ScHalt
{};

class Process;
class Reset;

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

    bool scheduled() const { return _scheduled; }
    void scheduled(bool new_val) { _scheduled = new_val; }

    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);
    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 signalReset(bool set, bool sync);

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

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

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

    void run();

    void addStatic(StaticSensitivity *);
    void setDynamic(DynamicSensitivity *);
    void clearDynamic() { setDynamic(nullptr); }
    void addReset(Reset *);

    ScEvent timeoutEvent;
    void setTimeout(::sc_core::sc_time t);
    void cancelTimeout();

    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;

    bool hasStaticSensitivities() { return !staticSensitivities.empty(); }
    bool internal() { return _internal; }
    bool timedOut() { return _timedOut; }
    bool inReset() { return _syncReset || syncResetCount || asyncResetCount; }

    bool dontInitialize() { return _dontInitialize; }
    void dontInitialize(bool di) { _dontInitialize = di; }

    void joinWait(::sc_core::sc_join *join) { joinWaiters.push_back(join); }

    void waitCount(int count) { _waitCount = count; }

    const char *uniqueName(const char *seed) { return nameGen.gen(seed); }

  protected:
    void timeout();

    Process(const char *name, ProcessFuncWrapper *func, bool internal=false);

    static Process *_newest;

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

    InternalScEvent _resetEvent;
    InternalScEvent _terminatedEvent;

    ProcessFuncWrapper *func;

    bool _internal;

    // Needed to support the deprecated "timed_out" function.
    bool _timedOut;

    bool _dontInitialize;

    bool _needsStart;
    bool _dynamic;
    bool _isUnwinding;
    bool _terminated;
    bool _scheduled;

    void terminate();

    bool _suspended;
    bool _suspendedReady;
    bool _disabled;

    bool _syncReset;

    int syncResetCount;
    int asyncResetCount;

    int _waitCount;

    int refCount;

    size_t stackSize;

    StaticSensitivities staticSensitivities;
    DynamicSensitivity *dynamicSensitivity;
    std::vector<Reset *> resets;

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

    std::vector<::sc_core::sc_join *> joinWaiters;

    UniqueNameGen nameGen;
};

class Reset
{
  public:
    Reset(Process *p, bool s, bool v) :
        _process(p), _signal(nullptr), _sync(s), _value(v)
    {}

    bool
    install(const sc_core::sc_signal_in_if<bool> *s)
    {
        _signal = s;

        if (_signal->_addReset(this)) {
            _process->addReset(this);
            if (_signal->read() == _value)
                update();
            return true;
        }
        return false;
    }
    void update() { _process->signalReset(_signal->read() == _value, _sync); }

    Process *process() { return _process; }
    const sc_core::sc_signal_in_if<bool> *signal() { return _signal; }
    bool sync() { return _sync; }
    bool value() { return _value; }

  private:
    Process *_process;
    const sc_core::sc_signal_in_if<bool> *_signal;
    bool _sync;
    bool _value;
};

void newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v);
void newReset(const sc_core::sc_signal_in_if<bool> *sig, Process *p,
        bool s, bool v);

} // namespace sc_gem5

#endif  //__SYSTEMC_CORE_PROCESS_HH__
