/*
 * 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_EXT_CORE_SC_SPAWN_HH__
#define __SYSTEMC_EXT_CORE_SC_SPAWN_HH__

#include <functional>
#include <vector>

#include "sc_join.hh"
#include "sc_process_handle.hh"

namespace sc_core
{

class sc_spawn_options;

} // namespace sc_core

namespace sc_gem5
{

class Process;

template <typename T>
struct ProcessObjFuncWrapper : public ProcessFuncWrapper
{
    T t;

    ProcessObjFuncWrapper(T t) : t(t) {}

    void call() override { t(); }
};

template <typename T, typename R>
struct ProcessObjRetFuncWrapper : public ProcessFuncWrapper
{
    T t;
    R *r;

    ProcessObjRetFuncWrapper(T t, R *r) : t(t), r(r) {}

    void call() override { *r = t(); }
};

Process *spawnWork(ProcessFuncWrapper *func, const char *name,
                   const ::sc_core::sc_spawn_options *);

} // namespace sc_gem5

namespace sc_core
{

template <class T>
class sc_in;
template <class T>
class sc_inout;
template <class T>
class sc_out;
template <class T>
class sc_signal_in_if;

class sc_event;
class sc_event_finder;
class sc_export_base;
class sc_interface;
class sc_port_base;

class sc_spawn_options
{
  public:
    friend ::sc_gem5::Process *::sc_gem5::spawnWork(
            ::sc_gem5::ProcessFuncWrapper *, const char *,
            const sc_spawn_options *);

    sc_spawn_options();

    void spawn_method();
    void dont_initialize();
    void set_stack_size(int);

    void set_sensitivity(const sc_event *);
    void set_sensitivity(sc_port_base *);
    void set_sensitivity(sc_export_base *);
    void set_sensitivity(sc_interface *);
    void set_sensitivity(sc_event_finder *);

    void reset_signal_is(const sc_in<bool> &, bool);
    void reset_signal_is(const sc_inout<bool> &, bool);
    void reset_signal_is(const sc_out<bool> &, bool);
    void reset_signal_is(const sc_signal_in_if<bool> &, bool);

    void async_reset_signal_is(const sc_in<bool> &, bool);
    void async_reset_signal_is(const sc_inout<bool> &, bool);
    void async_reset_signal_is(const sc_out<bool> &, bool);
    void async_reset_signal_is(const sc_signal_in_if<bool> &, bool);

  private:
    bool _spawnMethod;
    bool _dontInitialize;
    int _stackSize;
    std::vector<const sc_event *> _events;
    std::vector<sc_port_base *> _ports;
    std::vector<sc_export_base *> _exports;
    std::vector<sc_interface *> _interfaces;
    std::vector<sc_event_finder *> _finders;

    template <typename T>
    struct Reset
    {
        Reset(T *t, bool v, bool s) : target(t), value(v), sync(s) {}

        T *target;
        bool value;
        bool sync;
    };

    std::vector<Reset<const sc_in<bool> > > _in_resets;
    std::vector<Reset<const sc_inout<bool> > > _inout_resets;
    std::vector<Reset<const sc_out<bool> > > _out_resets;
    std::vector<Reset<const sc_signal_in_if<bool> > > _if_resets;

    // Disabled
    sc_spawn_options(const sc_spawn_options &) {}
    sc_spawn_options &operator = (const sc_spawn_options &) { return *this; }
};

template <typename T>
sc_process_handle
sc_spawn(T object, const char *name_p=nullptr,
         const sc_spawn_options *opt_p=nullptr)
{
    auto func = new ::sc_gem5::ProcessObjFuncWrapper<T>(object);
    ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p);
    return sc_process_handle() = p;
}

template <typename T>
sc_process_handle
sc_spawn(typename T::result_type *r_p, T object, const char *name_p=nullptr,
         const sc_spawn_options *opt_p=nullptr)
{
    auto func = new ::sc_gem5::ProcessObjRetFuncWrapper<
        T, typename T::result_type>(object, r_p);
    ::sc_gem5::Process *p = spawnWork(func, name_p, opt_p);
    return sc_process_handle() = p;
}

#define SC_FORK \
{ \
    ::sc_core::sc_process_handle forkees[] = {

#define SC_JOIN \
    }; \
    ::sc_core::sc_join join; \
    for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
        join.add_process(forkees[i]); \
    join.wait(); \
}

// Non-standard
#define SC_CJOIN \
    }; \
    ::sc_core::sc_join join; \
    for (int i = 0; i < sizeof(forkees) / sizeof(forkees[0]); i++) \
        join.add_process(forkees[i]); \
    join.wait_clocked(); \
}

// This avoids boost introduces a dependency on c++11. If that's a problem,
// we could imitate Accellera and pick which one to use on the fly.

template <typename F, typename... Args>
auto sc_bind(F &&f, Args && ...args) ->
    decltype(std::bind(std::forward<F>(f), std::forward<Args>(args)...))
{
    return std::bind(std::forward<F>(f), std::forward<Args>(args)...);
}

template <typename T>
auto sc_ref(T &&v) -> decltype(std::ref(std::forward<T>(v)))
{
    return std::ref(std::forward<T>(v));
}

template <typename T>
auto sc_cref(T &&v) -> decltype(std::cref(std::forward<T>(v)))
{
    return std::cref(std::forward<T>(v));
}

} // namespace sc_core

using sc_core::sc_bind;
using sc_core::sc_ref;
using sc_core::sc_cref;

namespace sc_unnamed
{

using namespace std::placeholders;

} // namespace sc_unnamed

#endif  //__SYSTEMC_EXT_CORE_SC_SPAWN_HH__
