//
// 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/noncopyable.hpp>
#include <uhd/transport/nirio/nirio_driver_iface.h>
#include <uhd/transport/nirio/nirio_quirks.h>
#include <uhd/transport/nirio/niriok_proxy.h>

namespace uhd { namespace niusrprio
{
   /* 
      This file defines the types, enumerations, and classes needed to 
      directly access a subset of the NI-RIO kernel interface.
      These definitions are specific to NI-RIO versions < 14.0.  These 
      are not compatible with NI-RIO 14.0 and later.
   */

    class UHD_API niriok_proxy_impl_v1 : virtual public niriok_proxy {
    public:
        niriok_proxy_impl_v1();
        virtual ~niriok_proxy_impl_v1();

        //File operations
        virtual nirio_status open(const std::string& interface_path);
        virtual void close(void);

        virtual nirio_status reset();

        virtual nirio_status get_version(
            nirio_version_t type,
            uint32_t& major,
            uint32_t& upgrade,
            uint32_t& maintenance,
            char& phase,
            uint32_t& build);

        virtual nirio_status get_attribute(
            const nirio_device_attribute32_t attribute,
            uint32_t& attrValue);

        virtual nirio_status set_attribute(
            const nirio_device_attribute32_t attribute,
            const uint32_t value);

        virtual nirio_status peek(uint32_t offset, uint32_t& value);

        virtual nirio_status peek(uint32_t offset, uint64_t& value);

        virtual nirio_status poke(uint32_t offset, const uint32_t& value);

        virtual nirio_status poke(uint32_t offset, const uint64_t& value);

        virtual nirio_status map_fifo_memory(
            uint32_t fifo_instance,
            size_t size,
            nirio_driver_iface::rio_mmap_t& map);

        virtual nirio_status unmap_fifo_memory(
            nirio_driver_iface::rio_mmap_t& map);

        virtual nirio_status stop_all_fifos();

        virtual nirio_status add_fifo_resource(const nirio_fifo_info_t& fifo_info);

        virtual nirio_status set_device_config();

        virtual nirio_status start_fifo(
            uint32_t channel);

        virtual nirio_status stop_fifo(
            uint32_t channel);

        virtual nirio_status configure_fifo(
            uint32_t channel,
            uint32_t requested_depth,
            uint8_t requires_actuals,
            uint32_t& actual_depth,
            uint32_t& actual_size);

        virtual nirio_status wait_on_fifo(
            uint32_t channel,
            uint32_t elements_requested,
            uint32_t scalar_type,
            uint32_t bit_width,
            uint32_t timeout,
            uint8_t output,
            void*& data_pointer,
            uint32_t& elements_acquired,
            uint32_t& elements_remaining);

        virtual nirio_status grant_fifo(
            uint32_t channel,
            uint32_t elements_to_grant);

        virtual nirio_status read_fifo(
            uint32_t channel,
            uint32_t elements_to_read,
            void* buffer,
            uint32_t buffer_datatype_width,
            uint32_t scalar_type,
            uint32_t bit_width,
            uint32_t timeout,
            uint32_t& number_read,
            uint32_t& number_remaining);

        virtual nirio_status write_fifo(
            uint32_t channel,
            uint32_t elements_to_write,
            void* buffer,
            uint32_t buffer_datatype_width,
            uint32_t scalar_type,
            uint32_t bit_width,
            uint32_t timeout,
            uint32_t& number_remaining);

        protected:
            // protected close function that doesn't acquire synchronization lock
            virtual void _close();

        private:
            nirio_status sync_operation(
                const void *writeBuffer,
                size_t writeBufferLength,
                void *readBuffer,
                size_t readBufferLength);
    };

}}
