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

  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 __MULTI_SOCKET_BASES_H__
#define __MULTI_SOCKET_BASES_H__

#include <systemc>
#include <tlm>

#include <map>
#include <sstream>

namespace tlm_utils {

template <typename signature>
struct fn_container{
  signature function;
};

#define TLM_DEFINE_FUNCTOR(name) \
template <typename MODULE, typename TRAITS> \
inline TLM_RET_VAL static_##name( void* mod \
                                       , void* fn \
                                       , int index \
                                       , TLM_FULL_ARG_LIST) \
{ \
  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
  MODULE* tmp_mod=static_cast<MODULE*>(mod); \
  fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
  return (tmp_mod->*(tmp_cb->function))(index, TLM_ARG_LIST_WITHOUT_TYPES); \
}\
\
template <typename MODULE, typename TRAITS> \
inline void delete_fn_container_of_##name(void* fn) \
{ \
  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
  fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
  if (tmp_cb) delete tmp_cb;\
} \
\
template <typename TRAITS> \
class name##_functor{ \
public: \
  typedef typename TRAITS::tlm_payload_type payload_type; \
  typedef typename TRAITS::tlm_phase_type   phase_type; \
  typedef TLM_RET_VAL (*call_fn)(void*,void*, int, TLM_FULL_ARG_LIST); \
  typedef void (*del_fn)(void*); \
\
  name##_functor(): m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0){} \
  ~name##_functor(){if (m_del_fn) (*m_del_fn)(m_mem_fn);}  \
\
  template <typename MODULE> \
  void set_function(MODULE* mod, TLM_RET_VAL (MODULE::*cb)(int, TLM_FULL_ARG_LIST)){ \
    typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
    m_fn=&static_##name<MODULE,TRAITS>;\
    m_del_fn=&delete_fn_container_of_##name<MODULE,TRAITS>;\
    m_del_fn(m_mem_fn); \
    fn_container_type* tmp= new fn_container_type(); \
    tmp->function=cb; \
    m_mod=static_cast<void*>(mod); \
    m_mem_fn=static_cast<void*>(tmp); \
  } \
  \
  TLM_RET_VAL operator()(int index, TLM_FULL_ARG_LIST){ \
    return m_fn(m_mod,m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
  } \
\
  bool empty(){return (m_mod==0 || m_mem_fn==0 || m_fn==0);}\
\
protected: \
  call_fn m_fn;\
  del_fn m_del_fn; \
  void* m_mod; \
  void* m_mem_fn; \
private: \
  name##_functor& operator=(const name##_functor&); \
}


#define TLM_RET_VAL tlm::tlm_sync_enum
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, typename TRAITS::tlm_phase_type& ph, sc_core::sc_time& t
#define TLM_ARG_LIST_WITHOUT_TYPES txn,ph,t
TLM_DEFINE_FUNCTOR(nb_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES

#define TLM_RET_VAL void
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, sc_core::sc_time& t
#define TLM_ARG_LIST_WITHOUT_TYPES txn,t
TLM_DEFINE_FUNCTOR(b_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES

#define TLM_RET_VAL unsigned int
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn
#define TLM_ARG_LIST_WITHOUT_TYPES txn
TLM_DEFINE_FUNCTOR(debug_transport);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES

#define TLM_RET_VAL bool
#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, tlm::tlm_dmi& dmi
#define TLM_ARG_LIST_WITHOUT_TYPES txn,dmi
TLM_DEFINE_FUNCTOR(get_dmi_ptr);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES

#define TLM_RET_VAL void
#define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
#define TLM_ARG_LIST_WITHOUT_TYPES l,u
TLM_DEFINE_FUNCTOR(invalidate_dmi);
#undef TLM_RET_VAL
#undef TLM_FULL_ARG_LIST
#undef TLM_ARG_LIST_WITHOUT_TYPES

#undef TLM_DEFINE_FUNCTOR

/*
This class implements the fw interface.
It allows to register a callback for each of the fw interface methods.
The callbacks simply forward the fw interface call, but add the id (an int)
of the callback binder to the signature of the call.
*/
template <typename TYPES>
class callback_binder_fw: public tlm::tlm_fw_transport_if<TYPES>{
  public:
    //typedefs according to the used TYPES class
    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 for the callbacks
    typedef nb_transport_functor<TYPES>    nb_func_type;
    typedef b_transport_functor<TYPES>     b_func_type;
    typedef debug_transport_functor<TYPES> debug_func_type;
    typedef get_dmi_ptr_functor<TYPES>     dmi_func_type;

    //ctor: an ID is needed to create a callback binder
    callback_binder_fw(int id): m_id(id), m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0), m_caller_port(0) {
    }

    //the nb_transport method of the fw interface
    sync_enum_type nb_transport_fw(transaction_type& txn,
                                phase_type& p,
                                sc_core::sc_time& t){
      //check if a callback is registered
      if ((m_nb_f == 0) || (m_nb_f && m_nb_f->empty())) {
        //std::cerr<<"No function registered"<<std::endl;
        SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_fw without a registered callback for nb_transport_fw.");
      }
      else
        return (*m_nb_f)(m_id, txn, p, t); //do the callback
      return tlm::TLM_ACCEPTED; //unreachable
    }
    
    //the b_transport method of the fw interface
    void b_transport(transaction_type& trans,sc_core::sc_time& t){
      //check if a callback is registered
      if ((m_b_f == 0) || (m_b_f && m_b_f->empty())) {
        SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to b_transport without a registered callback for b_transport.");
      }
      else
        (*m_b_f)(m_id, trans,t); //do the callback
    }
    
    //the DMI method of the fw interface
    bool get_direct_mem_ptr(transaction_type& trans, tlm::tlm_dmi&  dmi_data){
      //check if a callback is registered
      if ((m_dmi_f == 0) && (m_dmi_f && m_dmi_f->empty())) {
        dmi_data.allow_none();
        dmi_data.set_start_address(0x0);
        dmi_data.set_end_address((sc_dt::uint64)-1);
        return false;
      }
      else
        return (*m_dmi_f)(m_id, trans,dmi_data); //do the callback
    }
    
    //the debug method of the fw interface
    unsigned int transport_dbg(transaction_type& trans){
      //check if a callback is registered
      if ((m_dbg_f == 0) || (m_dbg_f && m_dbg_f->empty())) {
        return 0;
      }
      else
        return (*m_dbg_f)(m_id, trans); //do the callback
    }
    
    //the SystemC standard callback register_port:
    // - called when a port if bound to the interface
    // - allowd to find out who is bound to that callback binder
    void register_port(sc_core::sc_port_base& b, const char* name){
      m_caller_port=&b;
    }
    
    //register callbacks for all fw interface methods at once
    void set_callbacks(nb_func_type& cb1, b_func_type& cb2, dmi_func_type& cb3, debug_func_type& cb4){
      m_nb_f=&cb1;
      m_b_f=&cb2;
      m_dmi_f=&cb3;
      m_dbg_f=&cb4;
    }
    
    //getter method to get the port that is bound to that callback binder
    // NOTE: this will only return a valid value at end of elaboration
    //  (but not before end of elaboration!)
    sc_core::sc_port_base* get_other_side(){return m_caller_port;}
    
  private:
    //the ID of the callback binder
    int m_id; 
    
    //the callbacks
    nb_func_type* m_nb_f; 
    b_func_type*  m_b_f;
    debug_func_type* m_dbg_f;
    dmi_func_type* m_dmi_f;
    
    //the port bound to that callback binder
    sc_core::sc_port_base* m_caller_port;   
};

/*
This class implements the bw interface.
It allows to register a callback for each of the bw interface methods.
The callbacks simply forward the bw interface call, but add the id (an int)
of the callback binder to the signature of the call.
*/
template <typename TYPES>
class callback_binder_bw: public tlm::tlm_bw_transport_if<TYPES>{
  public:
    //typedefs according to the used TYPES class
    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 for the callbacks
    typedef nb_transport_functor<TYPES>   nb_func_type;
    typedef invalidate_dmi_functor<TYPES> dmi_func_type;

    //ctor: an ID is needed to create a callback binder
    callback_binder_bw(int id): m_id(id), m_nb_f(0), m_dmi_f(0) {
    }

    //the nb_transport method of the bw interface
    sync_enum_type nb_transport_bw(transaction_type& txn,
                                phase_type& p,
                                sc_core::sc_time& t){
      //check if a callback is registered
      if ((m_nb_f == 0) || (m_nb_f && m_nb_f->empty())) {
        SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_bw without a registered callback for nb_transport_bw");
      }
      else
        return (*m_nb_f)(m_id, txn, p, t); //do the callback
      return tlm::TLM_ACCEPTED; //unreachable
    }
    
    //the DMI method of the bw interface
    void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u){
      //check if a callback is registered
      if ((m_dmi_f == 0) || (m_dmi_f && m_dmi_f->empty())) {
        return;
      }
      else
        (*m_dmi_f)(m_id,l,u); //do the callback
    }

    //register callbacks for all bw interface methods at once
    void set_callbacks(nb_func_type& cb1, dmi_func_type& cb2){
      m_nb_f=&cb1;
      m_dmi_f=&cb2;
    }
    
  private:
    //the ID of the callback binder
    int m_id;
    //the callbacks
    nb_func_type* m_nb_f;
    dmi_func_type* m_dmi_f;
};


/*
This class forms the base for multi initiator sockets.
It enforces a multi initiator socket to implement all functions
needed to do hierarchical bindings.
*/
template <unsigned int BUSWIDTH = 32,
          typename TYPES = tlm::tlm_base_protocol_types,
          unsigned int N=0
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
          ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
#endif
          >
class multi_init_base: public tlm::tlm_initiator_socket<BUSWIDTH,
                                                  TYPES,
                                                  N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
                                                  ,POL
#endif
                                                  >{
public:
  //typedef for the base type: the standard tlm initiator socket
  typedef tlm::tlm_initiator_socket<BUSWIDTH,
                              TYPES,
                              N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
                              ,POL
#endif
                              > base_type;
  
  //this method shall disable the code that does the callback binding
  // that registers callbacks to binders
  virtual void disable_cb_bind()=0;
  
  //this method shall return the multi_init_base to which the
  // multi_init_base is bound hierarchically
  //  If the base is not bound hierarchically it shall return a pointer to itself
  virtual multi_init_base* get_hierarch_bind()=0;
  
  //this method shall return a vector of the callback binders of multi initiator socket
  virtual std::vector<callback_binder_bw<TYPES>* >& get_binders()=0;
  
  //this method shall return a vector of all target interfaces bound to this multi init socket
  virtual std::vector<tlm::tlm_fw_transport_if<TYPES>*>&  get_sockets()=0;
  
  //ctor and dtor
  virtual ~multi_init_base(){}
  multi_init_base():base_type(sc_core::sc_gen_unique_name("multi_init_base")){}
  multi_init_base(const char* name):base_type(name){}
};

/*
This class forms the base for multi target sockets.
It enforces a multi target socket to implement all functions
needed to do hierarchical bindings.
*/
template <unsigned int BUSWIDTH = 32,
          typename TYPES = tlm::tlm_base_protocol_types,
          unsigned int N=0
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
          ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
#endif
          >
class multi_target_base: public tlm::tlm_target_socket<BUSWIDTH, 
                                                TYPES,
                                                N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)                                                
                                                ,POL
#endif
                                                >{
public:
  //typedef for the base type: the standard tlm target socket
  typedef tlm::tlm_target_socket<BUSWIDTH, 
                              TYPES,
                              N
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
                              ,POL
#endif
                              > base_type;
  
  //this method shall return the multi_init_base to which the
  // multi_init_base is bound hierarchically
  //  If the base is not bound hierarchically it shall return a pointer to itself                                                
  virtual multi_target_base* get_hierarch_bind()=0;
  
  //this method shall inform the multi target socket that it is bound
  // hierarchically and to which other multi target socket it is bound hierarchically
  virtual void set_hierarch_bind(multi_target_base*)=0;
  
  //this method shall return a vector of the callback binders of multi initiator socket
  virtual std::vector<callback_binder_fw<TYPES>* >& get_binders()=0;
  
  //this method shall return a map of all multi initiator sockets that are bound to this multi target
  // the key of the map is the index at which the multi initiator i bound, while the value
  //  is the interface of the multi initiator socket that is bound at that index
  virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>&  get_multi_binds()=0;
  
  //ctor and dtor
  virtual ~multi_target_base(){}
  multi_target_base():base_type(sc_core::sc_gen_unique_name("multi_target_base")){}
  multi_target_base(const char* name):base_type(name){}
};

/*
All multi sockets must additionally derive from this class.
It enforces a multi socket to implement a function 
needed to do multi init to multi target bindings.
*/
template <typename TYPES>
class multi_to_multi_bind_base{
public:
  virtual ~multi_to_multi_bind_base(){}
  virtual tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>*)=0;
};

}
#endif
