/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/
#ifndef __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__
#define __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__

#include "tlm_utils/multi_socket_bases.h"

namespace tlm_utils
{

/*
This class implements a trivial multi target socket.
The triviality refers to the fact that the socket does not
do blocking to non-blocking or non-blocking to blocking conversions.

It allows to connect multiple initiators to this socket.
The user has to register callbacks for the fw interface methods
he likes to use. The callbacks are basically equal to the fw interface
methods but carry an additional integer that indicates to which
index of this socket the calling initiator is connected.
*/
template <typename MODULE, unsigned int BUSWIDTH=32,
          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
class multi_passthrough_target_socket :
    public multi_target_base< BUSWIDTH, TYPES, N, POL>,
    public multi_to_multi_bind_base<TYPES>
{
  public:
    //typedefs
    //  tlm 2.0 types for nb_transport
    typedef typename TYPES::tlm_payload_type transaction_type;
    typedef typename TYPES::tlm_phase_type phase_type;
    typedef tlm::tlm_sync_enum sync_enum_type;

    //  typedefs to keep the fn ptr notations short
    typedef sync_enum_type (MODULE::*nb_cb)(
            int, transaction_type &, phase_type &, sc_core::sc_time &);
    typedef void (MODULE::*b_cb)(int, transaction_type &, sc_core::sc_time &);
    typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type &txn);
    typedef bool (MODULE::*dmi_cb)(
            int, transaction_type &txn, tlm::tlm_dmi &dmi);

    typedef multi_target_base<BUSWIDTH, TYPES, N, POL> base_type;

    typedef typename base_type::base_initiator_socket_type
        base_initiator_socket_type;

    static const char *
    default_name()
    {
        return sc_core::sc_gen_unique_name("multi_passthrough_target_socket");
    }

    explicit multi_passthrough_target_socket(const char *name=default_name()) :
        base_type(name), m_hierarch_bind(0), m_eoe_disabled(false),
        m_export_callback_created(false)
    {}

    ~multi_passthrough_target_socket()
    {
        // Clean up everything allocated by 'new'.
        for (unsigned int i = 0; i < m_binders.size(); i++)
            delete m_binders[i];
    }

    void
    check_export_binding()
    {
        // If our export hasn't been bound yet (due to a hierarch binding)
        // we bind it now. We do that here as the user of the target port HAS
        // to bind at least on callback, otherwise the socket was useless.
        // Nevertheless, the target socket may still stay unbound afterwards.
        if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>>::
                get_interface()) {
            // We bind to a callback_binder that will be used as the first
            // interface i.e. calls to the sc_export will have the same ID as
            // calls from the first initator socket bound.
            callback_binder_fw<TYPES> *binder;

            if (m_binders.size() == 0) {
                binder = new callback_binder_fw<TYPES>(
                        this, m_binders.size());
                m_binders.push_back(binder);
                m_export_callback_created = true;
            } else {
                binder = m_binders[0];
            }

            sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>>::bind(*binder);
        }
    }

    //register callback for nb transport of fw interface
    void
    register_nb_transport_fw(MODULE *mod, nb_cb cb)
    {
        check_export_binding();

        // Warn if there already is a callback.
        if (m_nb_f.is_valid()) {
            display_warning("NBTransport_bw callback already registered.");
            return;
        }

        // Set the functor.
        m_nb_f.set_function(mod, cb);
    }

    // Register callback for b transport of fw interface.
    void
    register_b_transport(MODULE *mod, b_cb cb)
    {
        check_export_binding();

        // Warn if there already is a callback.
        if (m_b_f.is_valid()) {
            display_warning("BTransport callback already registered.");
            return;
        }

        // Set the functor.
        m_b_f.set_function(mod, cb);
    }

    // Register callback for debug transport of fw interface.
    void
    register_transport_dbg(MODULE *mod, dbg_cb cb)
    {
        check_export_binding();

        // Warn if there already is a callback.
        if (m_dbg_f.is_valid()) {
            display_warning("DebugTransport callback already registered.");
            return;
        }

        // Set the functor.
        m_dbg_f.set_function(mod, cb);
    }

    // Register callback for DMI of fw interface.
    void
    register_get_direct_mem_ptr(MODULE *mod, dmi_cb cb)
    {
        check_export_binding();

        // Warn if there already is a callback.
        if (m_dmi_f.is_valid()) {
            display_warning("DMI callback already registered.");
            return;
        }

        // Set the functor.
        m_dmi_f.set_function(mod, cb);
    }


    // Override virtual functions of the tlm_target_socket:
    // this function is called whenever an sc_port (as part of a init socket)
    // wants to bind to the export of the underlying tlm_target_socket
    // At this time a callback binder is created an returned to the sc_port
    // of the init socket, so that it binds to the callback binder.
    virtual tlm::tlm_fw_transport_if<TYPES> &
    get_base_interface()
    {
        // Error if this socket is already bound hierarchically.
        if (m_hierarch_bind)
            display_error("Socket already bound hierarchically.");

        if (m_export_callback_created) {
            // Consume binder created from the callback registration.
            m_export_callback_created = false;
        } else {
            m_binders.push_back(
                    new callback_binder_fw<TYPES>(this, m_binders.size()));
        }

        return *m_binders[m_binders.size()-1];
    }

    // Const overload not allowed for multi-sockets.
    virtual const tlm::tlm_fw_transport_if<TYPES> &
    get_base_interface() const
    {
        display_error("'get_base_interface() const'"
                " not allowed for multi-sockets.");
        return base_type::get_base_interface();
    }

    // Just return the export of the underlying tlm_target_socket in case of
    // a hierarchical bind.
    virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>> &
    get_base_export()
    {
        return *this;
    }

    // Just return the export of the underlying tlm_target_socket in case of
    // a hierarchical bind.
    virtual const sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>> &
    get_base_export() const
    {
        return base_type::get_base_export();
    }

    // The standard end of elaboration callback.
    void
    end_of_elaboration()
    {
        // 'break' here if the socket was told not to do callback binding.
        if (m_eoe_disabled)
            return;

        // Get the callback binders and the multi binds of the top of the
        // hierachical bind chain.
        // NOTE: this could be the same socket if there is no hierachical
        // bind.
        std::vector<callback_binder_fw<TYPES> *> &binders =
            get_hierarch_bind()->get_binders();
        std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
            multi_binds = get_hierarch_bind()->get_multi_binds();

        // Complete binding only if there has been a real bind.
        bool unbound = (binders.size() == 1 && m_export_callback_created);
        // No call to get_base_interface has consumed the export - ignore.
        if (unbound)
            return;

        // Iterate over all binders.
        for (unsigned int i = 0; i < binders.size(); i++) {
            // Set the callbacks for the binder.
            binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
            // Check if this connection is multi-multi.
            if (multi_binds.find(i) != multi_binds.end()) {
                // If so remember the interface.
                m_sockets.push_back(multi_binds[i]);
            } else {
                // If we are bound to a normal socket.
                // Get the calling port and try to cast it into a tlm socket
                // base.
                base_initiator_socket_type *test =
                    dynamic_cast<base_initiator_socket_type*>(
                            binders[i]->get_other_side());
                if (!test) {
                    display_error("Not bound to tlm_socket.");
                }
                // Remember the interface.
                m_sockets.push_back(&test->get_base_interface());
            }
        }
    }

    //
    // Bind multi target socket to multi target socket (hierarchical bind)
    //
    virtual void
    bind(base_type &s)
    {
        // Warn if already bound hierarchically.
        if (m_eoe_disabled) {
            display_warning("Socket already bound hierarchically. "
                    "Bind attempt ignored.");
            return;
        }

        // Disable our own end of elaboration call.
        disable_cb_bind();

        // Inform the bound target socket that it is bound
        // hierarchically now.
        s.set_hierarch_bind((base_type*)this);
        base_type::bind(s); // Satisfy SystemC.
    }

    // Operator notation for hierarchical bind.
    void operator () (base_type &s) { bind(s); }

    // Get access to sub port.
    tlm::tlm_bw_transport_if<TYPES> *
    operator [] (int i)
    {
        return m_sockets[i];
    }

    // Get number of bound initiators.
    // NOTE: this is only valid at end of elaboration!
    unsigned int size() { return get_hierarch_bind()->get_binders().size(); }

  protected:
    using base_type::display_warning;
    using base_type::display_error;

    // Implementation of base class interface.
    base_type *
    get_hierarch_bind()
    {
        if (m_hierarch_bind)
            return m_hierarch_bind->get_hierarch_bind();
        else
            return this;
    }
    std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
    get_multi_binds()
    {
        return m_multi_binds;
    }
    void set_hierarch_bind(base_type* h) { m_hierarch_bind = h; }
    tlm::tlm_fw_transport_if<TYPES> *
    get_last_binder(tlm::tlm_bw_transport_if<TYPES> *other)
    {
        m_multi_binds[m_binders.size() - 1] = other;
        return m_binders[m_binders.size() - 1];
    }

    // Map that stores to which index a multi init socket is connected
    // and the interface of the multi init socket.
    std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> m_multi_binds;

    void disable_cb_bind() { m_eoe_disabled = true; }
    std::vector<callback_binder_fw<TYPES> *> &
    get_binders()
    {
        return m_binders;
    }
    // Vector of connected sockets.
    std::vector<tlm::tlm_bw_transport_if<TYPES> *> m_sockets;
    // Vector of binders that convert untagged interface into tagged
    // interface.
    std::vector<callback_binder_fw<TYPES> *> m_binders;

    base_type *m_hierarch_bind; // Pointer to hierarchical bound multi port.
    // bool that disables callback bindings at end of elaboration.
    bool m_eoe_disabled;
    // bool that indicates that a binder has been created from a callback
    // registration.
    bool m_export_callback_created;

    // callbacks as functors
    // (allows to pass the callback to another socket that does not know
    // the type of the module that owns the callbacks).
    typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
    typename callback_binder_fw<TYPES>::b_func_type m_b_f;
    typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
    typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;
};

template <typename MODULE, unsigned int BUSWIDTH=32,
          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0>
class multi_passthrough_target_socket_optional :
    public multi_passthrough_target_socket<
        MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND>
{
    typedef multi_passthrough_target_socket<
        MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
  public:
    multi_passthrough_target_socket_optional() : socket_b() {}
    explicit multi_passthrough_target_socket_optional(const char *name) :
        socket_b(name)
    {}
};

} // namespace tlm_utils

#endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__ */
