# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright 2026 Advanced Micro Devices, Inc. All rights reserved.

import unittest
import datetime
import time
import os
import errno

from pyverbs.libibverbs_enums import ibv_qp_type, ibv_wc_status, ibv_wr_opcode, ibv_create_cq_wc_flags, \
    IBV_WC_STANDARD_FLAGS
from tests.base import RCResources, RDMATestCase
from pyverbs.pyverbs_error import PyverbsRDMAError
from pyverbs.cq import CqInitAttrEx, CQEX
from pyverbs.qp import QPInitAttr
from pyverbs.cq import PollCqAttr
import tests.utils as u

GIGA = 1000000000
CLOCKFD = 3
CLOCKID_TYPE_BITS = 3

def timestamp_res_cls(base_class):
    """
    This is a factory function which creates a class that inherits base_class of
    any BaseResources type.
    :param base_class: The base resources class to inherit from.
    :return: TimeStampRes class.
    """
    class TimeStampRes(base_class):
        def __init__(self, dev_name, ib_port, gid_index, qp_type, send_ts=None,
                     recv_ts=None):
            self.qp_type = qp_type
            self.send_ts = send_ts
            self.recv_ts = recv_ts
            self.timestamp = None
            self.scq = None
            self.rcq = None
            self.phc_file = None
            self.open_phc_dev(dev_name)
            super().__init__(dev_name=dev_name, ib_port=ib_port, gid_index=gid_index)

        def close_files(self):
            if self.phc_file is not None:
                self.phc_file.close()
                self.phc_file = None

        def open_phc_dev(self, dev_name):
            try:
                phc_name = os.listdir(f'/sys/class/infiniband/{dev_name}/device/ptp')[0]
                self.phc_file = open(f'/dev/{phc_name}', 'rb')
                self.phc_clkid = (~self.phc_file.fileno() << CLOCKID_TYPE_BITS) | CLOCKFD
            except (FileNotFoundError, OSError, IndexError):
                raise unittest.SkipTest('No PHC or failed to open')

        def read_phc(self):
            return time.clock_gettime(self.phc_clkid)

        def create_cq(self):
            self.scq = self._create_ex_cq(self.send_ts)
            self.rcq = self._create_ex_cq(self.recv_ts)

        def _create_ex_cq(self, timestamp=None):
            """
            Create an Extended CQ.
            :param timestamp: If set, the timestamp type to use.
            """
            wc_flags = IBV_WC_STANDARD_FLAGS
            if timestamp:
                wc_flags |= timestamp
            cia = CqInitAttrEx(cqe=self.num_msgs, wc_flags=wc_flags)
            try:
                cq = CQEX(self.ctx, cia)
            except PyverbsRDMAError as ex:
                if ex.error_code == errno.EOPNOTSUPP:
                    raise unittest.SkipTest('Create Extended CQ is not supported')
                raise ex
            return cq

        def create_qp_init_attr(self):
            return QPInitAttr(qp_type=self.qp_type, scq=self.scq,
                              rcq=self.rcq, srq=self.srq, cap=self.create_qp_cap())

    return TimeStampRes


class TimeStampTest(RDMATestCase):
    """
    Test various types of timestamping formats.
    """
    def setUp(self):
        super().setUp()
        self.send_ts = None
        self.recv_ts = None
        self.qp_type = None

    def tearDown(self):
        for player in [getattr(self, 'client', None), getattr(self, 'server', None)]:
            if player is not None and hasattr(player, 'close_files'):
                player.close_files()
        super().tearDown()

    @property
    def resource_arg(self):
        return {'send_ts': self.send_ts, 'recv_ts': self.recv_ts,
                'qp_type': self.qp_type}

    def test_timestamp_free_running_rc_traffic(self):
        """
        Test free-running timestamp on RC traffic.
        The timestamp is returned as a raw HW PHC tick value, so this test
        only verifies that polling succeeds; value validation is done by the
        real-time variant.
        """
        self.qp_type = ibv_qp_type.IBV_QPT_RC
        self.send_ts = self.recv_ts = ibv_create_cq_wc_flags.IBV_WC_EX_WITH_COMPLETION_TIMESTAMP
        self.create_players(timestamp_res_cls(RCResources), **self.resource_arg)
        self.ts_traffic()

    def test_timestamp_real_time_rc_traffic(self):
        """
        Test real-time timestamp on RC traffic.
        The timestamp is returned in nanoseconds and validated against the
        live PHC read from /dev/ptpN.
        """
        self.qp_type = ibv_qp_type.IBV_QPT_RC
        self.send_ts = self.recv_ts = ibv_create_cq_wc_flags.IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK
        self.create_players(timestamp_res_cls(RCResources), **self.resource_arg)
        self.ts_traffic()
        self.verify_ts(self.client.timestamp / GIGA, self.client.read_phc())
        self.verify_ts(self.server.timestamp / GIGA, self.server.read_phc())

    def verify_ts(self, timestamp, phc_now):
        """
        Verify that the timestamp is in the past one second
        """
        if self.config['verbosity']:
            print(f'timestamp {timestamp} current {phc_now} difference {phc_now - timestamp}')
        if timestamp > phc_now:
            raise PyverbsRDMAError(f'Completion timestamp is in the future: {timestamp} > {phc_now}')
        if timestamp < phc_now - 1:
            raise PyverbsRDMAError(f'Completion timestamp is too far in the past: {timestamp} < {phc_now - 1}')

    @staticmethod
    def poll_cq_ex_ts(cqex, ts_type=None):
        """
        Poll completion from the extended CQ.
        :param cqex: CQEX to poll from
        :param ts_type: If set, read the CQE timestamp in this format
        :return: The CQE timestamp if it requested.
        """
        polling_timeout = 10
        start = datetime.datetime.now()
        ts = 0

        poll_attr = PollCqAttr()
        ret = cqex.start_poll(poll_attr)
        while ret == 2 and (datetime.datetime.now() - start).seconds < polling_timeout:
            ret = cqex.start_poll(poll_attr)
        if ret == 2:
            raise PyverbsRDMAError('Failed to poll CQEX - Got timeout')
        if ret != 0:
            raise PyverbsRDMAError('Failed to poll CQEX')
        if cqex.status != ibv_wc_status.IBV_WC_SUCCESS:
            raise PyverbsRDMAError(f'Completion status is {cqex.status}')
        if ts_type == ibv_create_cq_wc_flags.IBV_WC_EX_WITH_COMPLETION_TIMESTAMP:
            ts = cqex.read_timestamp()
        if ts_type == ibv_create_cq_wc_flags.IBV_WC_EX_WITH_COMPLETION_TIMESTAMP_WALLCLOCK:
            ts = cqex.read_completion_wallclock_ns()
        cqex.end_poll()
        return ts

    def ts_traffic(self):
        """
        Run RDMA traffic and read the completions timestamps.
        """
        s_recv_wr = u.get_recv_wr(self.server)
        u.post_recv(self.server, s_recv_wr)
        c_send_wr, _ = u.get_send_elements(self.client, False)
        u.send(self.client, c_send_wr, ibv_wr_opcode.IBV_WR_SEND, False, 0)
        self.client.timestamp = self.poll_cq_ex_ts(self.client.scq, ts_type=self.send_ts)
        self.server.timestamp = self.poll_cq_ex_ts(self.server.rcq, ts_type=self.recv_ts)
