//
// Copyright 2013-2014 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//


#pragma once

#include <uhd/utils/log.hpp>
#include <stdint.h>
#include <set>

// Quirk#1: We need to verify RX zero-copy data transfers from the RIO
//          driver if we are in full duplex mode.
//          This option allows enabling this quirk.
#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 0

namespace uhd { namespace niusrprio {

class nirio_quirks
{
public:
    nirio_quirks() : _tx_stream_count(0) {}

    UHD_INLINE void register_tx_streams(const uint32_t tx_stream_indices[], size_t size)
    {
        for (size_t i = 0; i < size; i++) {
            _tx_stream_fifo_indices.insert(tx_stream_indices[i]);
        }
    }

    UHD_INLINE void add_tx_fifo(uint32_t index)
    {
        if (_tx_stream_fifo_indices.find(index) != _tx_stream_fifo_indices.end()) {
            if (_tx_stream_count == 0) {
                UHD_LOGGER_DEBUG("NIRIO")
                    << "NI-RIO RX FIFO Transfer Check Quirk Enabled.";
            }
            _tx_stream_count++;
        }
    }

    UHD_INLINE void remove_tx_fifo(uint32_t index)
    {
        if (_tx_stream_fifo_indices.find(index) != _tx_stream_fifo_indices.end()) {
            _tx_stream_count--;
            if (_tx_stream_count == 0) {
                UHD_LOGGER_DEBUG("NIRIO")
                    << "NI-RIO RX FIFO Transfer Check Quirk Disabled.";
            }
        }
    }

    // Quirk#1: We need to verify RX zero-copy data transfers from the RIO
    //          driver if we are in full duplex mode.
    //          This function returns true if the quirk is enabled for the
    //          current uhd_device configuration (dynamic)
    UHD_INLINE bool rx_fifo_xfer_check_en() const
    {
        // This function must be as fast as possible because it is in a high
        // throughput data path
        return _tx_stream_count > 0;
    }

private:
    std::set<uint32_t> _tx_stream_fifo_indices;
    size_t _tx_stream_count;
};

}} // namespace uhd::niusrprio
