# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2020 Nvidia Corporation. All rights reserved. See COPYING file

import unittest
import errno

from pyverbs.providers.mlx5.mlx5dv import Mlx5DVQPInitAttr, Mlx5QP, \
    Mlx5DVDCInitAttr, Mlx5Context
from tests.test_rdmacm import CMAsyncConnection
from tests.mlx5_base import Mlx5PyverbsAPITestCase, Mlx5RDMACMBaseTest
from pyverbs.pyverbs_error import PyverbsRDMAError
from pyverbs.srq import SRQ, SrqInitAttr, SrqAttr
from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_qp_init_attr_mask, mlx5dv_dc_type
from tests.base_rdmacm import AsyncCMResources
from pyverbs.qp import QPCap, QPInitAttrEx
from pyverbs.cmid import ConnParam
from tests.base import DCT_KEY
from pyverbs.addr import AH
from pyverbs.libibverbs_enums import ibv_wr_opcode, ibv_qp_create_send_ops_flags, ibv_qp_init_attr_mask, \
    ibv_qp_type, ibv_qp_state
from pyverbs.cq import CQ
import tests.utils as u


class DcCMConnection(CMAsyncConnection):
    """
    Implement RDMACM connection management for asynchronous CMIDs using DC as
    an external QP.
    """
    def create_cm_res(self, ip_addr, passive, **kwargs):
        self.cm_res = DcCMResources(addr=ip_addr, passive=passive, **kwargs)
        if passive:
            self.cm_res.create_cmid()
        else:
            for conn_idx in range(self.num_conns):
                self.cm_res.create_cmid(conn_idx)
        self.get_and_update_addrinfo(passive, ip_addr)

    def _ext_qp_server_traffic(self):
        recv_wr = u.get_recv_wr(self.cm_res)
        for _ in range(self.cm_res.num_msgs):
            u.post_recv(self.cm_res, recv_wr)
        self.syncer.wait()
        for _ in range(self.cm_res.num_msgs):
            u.poll_cq(self.cm_res.cq)

    def _ext_qp_client_traffic(self):
        self.cm_res.remote_dct_num = self.cm_res.remote_qpn
        _, send_wr = u.get_send_elements(self.cm_res, self.cm_res.passive)
        ah = AH(self.cm_res.cmid.pd, attr=self.cm_res.remote_ah)
        self.syncer.wait()
        for send_idx in range(self.cm_res.num_msgs):
            dci_idx = send_idx % len(self.cm_res.qps)
            u.post_send_ex(self.cm_res, send_wr, ibv_wr_opcode.IBV_WR_SEND, ah=ah,
                           qp_idx=dci_idx)
            u.poll_cq(self.cm_res.cq)

    def disconnect(self):
        if self.cm_res.reserved_qp_num and self.cm_res.passive:
            Mlx5Context.reserved_qpn_dealloc(self.cm_res.child_id.context,
                                             self.cm_res.reserved_qp_num)
            self.cm_res.reserved_qp_num = 0
        super().disconnect()


class DcCMResources(AsyncCMResources):
    """
    DcCMResources class contains resources for RDMA CM asynchronous
    communication using DC as an external QP.
    """
    def __init__(self, addr=None, passive=None, **kwargs):
        """
        Init DcCMResources instance.
        :param passive: Indicate if this CM is the passive CM.
        """
        super().__init__(passive=passive, **kwargs)
        self.srq = None
        self.remote_dct_num = None
        self.reserved_qp_num = 0

    def create_qp(self, conn_idx=0):
        """
        Create an RDMACM QP. If self.with_ext_qp is set, then an external CQ and
        DC QP will be created. In case that CQ is already created, it is used
        for the newly created QP.
        """
        try:
            if not self.passive:
                # Create the DCI QPs.
                cmid = self.cmids[conn_idx]
                self.create_cq(cmid)
                qp_init_attr = self.create_qp_init_attr(cmid, ibv_qp_create_send_ops_flags.IBV_QP_EX_WITH_SEND)
                attr = Mlx5DVQPInitAttr(comp_mask=mlx5dv_qp_init_attr_mask.MLX5DV_QP_INIT_ATTR_MASK_DC,
                                        dc_init_attr=Mlx5DVDCInitAttr())
                self.qps[conn_idx] = Mlx5QP(cmid.context, qp_init_attr, attr)

            if self.passive and conn_idx == 0:
                # Create the DCT QP only for the first connection.
                cmid = self.child_id
                self.create_cq(cmid)
                self.create_srq(cmid)
                qp_init_attr = self.create_qp_init_attr(cmid)
                dc_attr = Mlx5DVDCInitAttr(dc_type=mlx5dv_dc_type.MLX5DV_DCTYPE_DCT,
                                           dct_access_key=DCT_KEY)
                attr = Mlx5DVQPInitAttr(comp_mask=mlx5dv_qp_init_attr_mask.MLX5DV_QP_INIT_ATTR_MASK_DC,
                                        dc_init_attr=dc_attr)
                self.qps[conn_idx] = Mlx5QP(cmid.context, qp_init_attr, attr)
        except PyverbsRDMAError as ex:
            if ex.error_code == errno.EOPNOTSUPP:
                raise unittest.SkipTest('Create DC QP is not supported')
            raise ex

    def create_qp_cap(self):
        return QPCap(self.num_msgs, 0, 1, 0)

    def create_qp_init_attr(self, cmid, send_ops_flags=0):
        comp_mask = ibv_qp_init_attr_mask.IBV_QP_INIT_ATTR_PD
        if send_ops_flags:
            comp_mask |= ibv_qp_init_attr_mask.IBV_QP_INIT_ATTR_SEND_OPS_FLAGS
        return QPInitAttrEx(cap=self.create_qp_cap(), pd=cmid.pd, scq=self.cq,
                            rcq=self.cq, srq=self.srq, qp_type=ibv_qp_type.IBV_QPT_DRIVER,
                            send_ops_flags=send_ops_flags, comp_mask=comp_mask,
                            sq_sig_all=1)

    def create_srq(self, cmid):
        srq_init_attr = SrqInitAttr(SrqAttr(max_wr=self.num_msgs))
        try:
            self.srq = SRQ(cmid.pd, srq_init_attr)
        except PyverbsRDMAError as ex:
            if ex.error_code == errno.EOPNOTSUPP:
                raise unittest.SkipTest('Create SRQ is not supported')
            raise ex

    def modify_ext_qp_to_rts(self, conn_idx=0):
        cmids = self.child_ids if self.passive else self.cmids
        if not self.passive or not conn_idx:
            qp = self.qps[conn_idx]
            attr, _ = cmids[conn_idx].init_qp_attr(ibv_qp_state.IBV_QPS_INIT)
            qp.to_init(attr)
            attr, _ = cmids[conn_idx].init_qp_attr(ibv_qp_state.IBV_QPS_RTR)
            qp.to_rtr(attr)
            if not self.passive:
                # The passive QP is DCT which should stay in RTR state.
                self.remote_ah = attr.ah_attr
                attr, _ = cmids[conn_idx].init_qp_attr(ibv_qp_state.IBV_QPS_RTS)
                qp.to_rts(attr)

    def create_conn_param(self, qp_num=0, conn_idx=0):
        if conn_idx and self.passive:
            try:
                ctx = self.child_id.context
                self.reserved_qp_num = Mlx5Context.reserved_qpn_alloc(ctx)
            except PyverbsRDMAError as ex:
                if ex.error_code == errno.EOPNOTSUPP:
                    raise unittest.SkipTest('Alloc reserved QP number is not supported')
                raise ex
            qp_num = self.reserved_qp_num
        else:
            qp_num = self.qps[conn_idx].qp_num
        return ConnParam(qp_num=qp_num)


class Mlx5CMTestCase(Mlx5RDMACMBaseTest):
    """
    Mlx5 RDMACM test class.
    """
    def test_rdmacm_async_traffic_dc_external_qp(self):
        """
        Connect multiple RDMACM connections using DC as an external QP for
        traffic.
        """
        self.two_nodes_rdmacm_traffic(DcCMConnection, self.rdmacm_traffic,
                                      with_ext_qp=True, num_conns=2)


class ReservedQPTest(Mlx5PyverbsAPITestCase):

    def test_reservered_qpn(self):
        """
        Alloc reserved qpn multiple times and then dealloc the qpns. In addition,
        the test includes bad flows where a fake qpn gets deallocated, and a
        real qpn gets deallocated twice.
        """
        try:
            # Alloc qp number multiple times.
            qpns = []
            for i in range(1000):
                qpns.append(Mlx5Context.reserved_qpn_alloc(self.ctx))
            for i in range(1000):
                Mlx5Context.reserved_qpn_dealloc(self.ctx, qpns[i])

            # Dealloc qp number that was not allocated.
            qpn = Mlx5Context.reserved_qpn_alloc(self.ctx)
            with self.assertRaises(PyverbsRDMAError) as ex:
                fake_qpn = qpn - 1
                Mlx5Context.reserved_qpn_dealloc(self.ctx, fake_qpn)
            self.assertEqual(ex.exception.error_code, errno.EINVAL)

            # Try to dealloc same qp number twice.
            Mlx5Context.reserved_qpn_dealloc(self.ctx, qpn)
            with self.assertRaises(PyverbsRDMAError) as ex:
                Mlx5Context.reserved_qpn_dealloc(self.ctx, qpn)
            self.assertEqual(ex.exception.error_code, errno.EINVAL)

        except PyverbsRDMAError as ex:
            if ex.error_code == errno.EOPNOTSUPP:
                raise unittest.SkipTest('Alloc reserved QP number is not supported')
            raise ex
