# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2019 Mellanox Technologies, Inc . All rights reserved. See COPYING file

import abc

from pyverbs.cmid import CMID, AddrInfo, CMEventChannel, ConnParam, UDParam
from pyverbs.qp import QPCap, QPInitAttr, QPAttr, QP
from pyverbs.pyverbs_error import PyverbsUserError
import pyverbs.cm_enums as ce
import pyverbs.enums as e
from pyverbs.cq import CQ


GRH_SIZE = 40
qp_type_per_ps = {ce.RDMA_PS_TCP: e.IBV_QPT_RC, ce.RDMA_PS_UDP: e.IBV_QPT_UD,
                  ce.RDMA_PS_IPOIB : e.IBV_QPT_UD}


class CMResources(abc.ABC):
    """
    CMResources class is an abstract base class which contains basic resources
    for RDMA CM communication.
    """
    def __init__(self, addr=None, passive=None, **kwargs):
        """
        :param addr: Local address to bind to.
        :param passive: Indicate if this CM is the passive CM.
        :param kwargs: Arguments:
            * *port* (str)
                Port number of the address
            * *with_ext_qp* (bool)
                If set, an external RC QP will be created and used by RDMACM
            * *port_space* (str)
                If set, indicates the CMIDs port space
        """
        self.qp_init_attr = None
        self.passive = passive
        self.with_ext_qp = kwargs.get('with_ext_qp', False)
        self.port = kwargs.get('port') if kwargs.get('port') else '7471'
        self.ib_port = int(kwargs.get('ib_port', '1'))
        self.port_space = kwargs.get('port_space', ce.RDMA_PS_TCP)
        self.remote_operation = kwargs.get('remote_op')
        self.qp_type = qp_type_per_ps[self.port_space]
        self.qp_init_attr = QPInitAttr(qp_type=self.qp_type, cap=QPCap())
        self.connected = False
        # When passive side (server) listens to incoming connection requests,
        # for each new request it creates a new cmid which is used to establish
        # the connection with the remote side
        self.msg_size = 1024
        self.num_msgs = 10
        self.channel = None
        self.cq = None
        self.qps = {}
        self.mr = None
        self.remote_qpn = None
        self.ud_params = None
        self.child_ids = {}
        self.cmids = {}
        if self.passive:
            self.ai = AddrInfo(src=addr, src_service=self.port,
                               port_space=self.port_space, flags=ce.RAI_PASSIVE)
        else:
            self.ai = AddrInfo(src=addr, dst=addr, dst_service=self.port,
                               port_space=self.port_space)

    @property
    def child_id(self):
        if self.child_ids:
            return self.child_ids[0]

    @property
    def cmid(self):
        if self.cmids:
            return self.cmids[0]

    @property
    def qp(self):
        if self.qps:
            return self.qps[0]

    def create_mr(self):
        cmid = self.child_id if self.passive else self.cmid
        mr_remote_function = {None: cmid.reg_msgs, 'read': cmid.reg_read,
                              'write': cmid.reg_write}
        self.mr = mr_remote_function[self.remote_operation](self.msg_size + GRH_SIZE)

    def create_event_channel(self):
        self.channel = CMEventChannel()

    def create_qp_init_attr(self, rcq=None, scq=None):
        return QPInitAttr(qp_type=self.qp_type, rcq=rcq, scq=scq,
                          cap=QPCap(max_recv_wr=1))

    def create_conn_param(self, qp_num=0, conn_idx=0):
        if self.with_ext_qp:
            qp_num = self.qp.qp_num
        return ConnParam(qp_num=qp_num)

    def set_ud_params(self, cm_event):
        if self.port_space in [ce.RDMA_PS_UDP, ce.RDMA_PS_IPOIB]:
            self.ud_params = UDParam(cm_event)

    def my_qp_number(self):
        if self.with_ext_qp:
            return self.qp.qp_num
        else:
            cm = self.child_id if self.passive else self.cmid
            return cm.qpn

    def create_qp(self, conn_idx=0):
        """
        Create an rdmacm QP. If self.with_ext_qp is set, then an external CQ and
        QP will be created. In case that CQ is already created, it is used
        for the newly created QP.
        :param conn_idx: The connection index.
        """
        cmid = self.child_id if self.passive else self.cmid
        if not self.with_ext_qp:
            cmid.create_qp(self.create_qp_init_attr())
        else:
            self.create_cq(cmid)
            init_attr = self.create_qp_init_attr(rcq=self.cq, scq=self.cq)
            self.qps[conn_idx] = QP(cmid.pd, init_attr, QPAttr())

    def create_cq(self, cmid):
        if not self.cq:
            self.cq = CQ(cmid.context, self.num_msgs, None, None, 0)

    def modify_ext_qp_to_rts(self, conn_idx=0):
        cmid = self.child_id if self.passive else self.cmid
        attr, mask = cmid.init_qp_attr(e.IBV_QPS_INIT)
        self.qps[conn_idx].modify(attr, mask)
        attr, mask = cmid.init_qp_attr(e.IBV_QPS_RTR)
        self.qps[conn_idx].modify(attr, mask)
        attr, mask = cmid.init_qp_attr(e.IBV_QPS_RTS)
        self.qps[conn_idx].modify(attr, mask)

    def mem_write(self, data, size, offset=0):
        self.mr.write(data, size, offset)

    def mem_read(self, size=None, offset=0):
        size_ = self.msg_size if size is None else size
        return self.mr.read(size_, offset)

    @abc.abstractmethod
    def create_child_id(self, cm_event=None):
        pass

    @property
    def mr_lkey(self):
        return self.mr.lkey


class AsyncCMResources(CMResources):
    """
    AsyncCMResources class contains resources for RDMA CM asynchronous
    communication.
    :param addr: Local address to bind to.
    :param passive: Indicate if this CM is the passive CM.
    """
    def __init__(self, addr=None, passive=None, **kwargs):
        super(AsyncCMResources, self).__init__(addr=addr, passive=passive,
                                               **kwargs)
        self.create_event_channel()

    def create_cmid(self, idx=0):
        self.cmids[idx] = CMID(creator=self.channel, port_space=self.port_space)

    def create_child_id(self, cm_event=None):
        if not self.passive:
            raise PyverbsUserError('create_child_id can be used only in passive side')
        new_child_idx = len(self.child_ids)
        self.child_ids[new_child_idx] = CMID(creator=cm_event, listen_id=self.cmid)


class SyncCMResources(CMResources):
    """
    SyncCMResources class contains resources for RDMA CM synchronous
    communication.
    :param addr: Local address to bind to.
    :param passive: Indicate if this CM is the passive CM.
    """
    def __init__(self, addr=None, passive=None, **kwargs):
        super(SyncCMResources, self).__init__(addr=addr, passive=passive,
                                              **kwargs)

    def create_cmid(self, idx=0):
        self.cmids[idx] = CMID(creator=self.ai, qp_init_attr=self.qp_init_attr)

    def create_child_id(self, cm_event=None):
        if not self.passive:
            raise PyverbsUserError('create_child_id can be used only in passive side')
        new_child_idx = len(self.child_ids)
        self.child_ids[new_child_idx] = self.cmid.get_request()
