# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2020 Mellanox Technologies, Inc. All rights reserved. See COPYING file
"""
Test module for Shared PD.
"""
import unittest
import errno
import os

from tests.test_qpex import QpExRCRDMAWrite
from tests.base import RDMATestCase
from pyverbs.device import Context
from pyverbs.pd import PD
from pyverbs.mr import MR
import pyverbs.enums as e
import tests.utils as u


def get_import_res_class(base_class):
    """
    This function creates a class that inherits base_class of any BaseResources
    type. Its purpose is to behave exactly as base_class does, except for the
    objects creation, which instead of creating context, PD and MR, it imports
    them. Hence the returned class must be initialized with (cmd_fd, pd_handle,
    mr_handle, mr_addr, **kwargs), while kwargs are the arguments needed
    (if any) for base_class. In addition it has unimport_resources() method
    which unimprot all the resources and closes the imported PD object.
    :param base_class: The base resources class to inherit from
    :return: ImportResources(cmd_fd, pd_handle, mr_handle, mr_addr, **kwargs)
             class
    """
    class ImportResources(base_class):
        def __init__(self, cmd_fd, pd_handle, mr_handle, mr_addr=None, **kwargs):
            self.cmd_fd = cmd_fd
            self.pd_handle = pd_handle
            self.mr_handle = mr_handle
            self.mr_addr = mr_addr
            super(ImportResources, self).__init__(**kwargs)

        def create_context(self):
            try:
                self.ctx = Context(cmd_fd=self.cmd_fd)
            except u.PyverbsRDMAError as ex:
                if ex.error_code in [errno.EOPNOTSUPP, errno.EPROTONOSUPPORT]:
                    raise unittest.SkipTest('Importing a device is not supported')
                raise ex

        def create_pd(self):
            self.pd = PD(self.ctx, handle=self.pd_handle)

        def create_mr(self):
            self.mr = MR(self.pd, handle=self.mr_handle, address=self.mr_addr)

        def unimport_resources(self):
            self.mr.unimport()
            self.pd.unimport()
            self.pd.close()

    return ImportResources


class SharedPDTestCase(RDMATestCase):
    def setUp(self):
        super().setUp()
        self.iters = 10
        self.server_res = None
        self.imported_res = []

    def tearDown(self):
        for res in self.imported_res:
            res.unimport_resources()
        super().tearDown()

    def test_imported_rc_ex_rdma_write(self):
        setup_params = {'dev_name': self.dev_name, 'ib_port': self.ib_port,
                        'gid_index': self.gid_index}
        self.server_res = QpExRCRDMAWrite(**setup_params)
        cmd_fd_dup = os.dup(self.server_res.ctx.cmd_fd)
        import_cls = get_import_res_class(QpExRCRDMAWrite)
        server_import = import_cls(
            cmd_fd_dup, self.server_res.pd.handle, self.server_res.mr.handle,
            # The imported MR's address is NULL, so using the address of the
            # "main" MR object to be able to validate the message
            self.server_res.mr.buf,
            **setup_params)
        self.imported_res.append(server_import)
        client = QpExRCRDMAWrite(**setup_params)
        client.pre_run(server_import.psns, server_import.qps_num)
        server_import.pre_run(client.psns, client.qps_num)
        client.rkey = server_import.mr.rkey
        server_import.rkey = client.mr.rkey
        client.raddr = server_import.mr.buf
        server_import.raddr = client.mr.buf
        u.rdma_traffic(client, server_import, self.iters, self.gid_index,
                       self.ib_port, send_op=e.IBV_WR_RDMA_WRITE, new_send=True)
