/*
 * 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; }
};

void sc_spawn_warn_unimpl(const char *func);

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__
