/*
 * This RPC server stub was autogenerated by idlc (version 8a02fc5d). DO NOT EDIT!
 * Generated from DiskDriver.idl for interface DiskDriver at 2021-06-26T17:21:52-0500
 *
 * You should subclass this implementation and define the required abstract methods to complete
 * implementing the interface. Note that there are several helper methods available to simplify
 * this task, or to retrieve more information about the caller.
 *
 * See the full RPC documentation for more details.
 */
#ifndef RPC_SERVER_GENERATED_17065700451208530523
#define RPC_SERVER_GENERATED_17065700451208530523

#include <string>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
#include <string_view>
#include <vector>

#define RPC_USER_TYPES_INCLUDES
#include <DriverSupport/disk/Types.h>
#undef RPC_USER_TYPES_INCLUDES

namespace rpc {
namespace rt { class ServerRpcIoStream; }
class DiskDriverServer {
    struct MessageHeader {
        enum Flags: uint32_t {
            Request                     = (1 << 0),
            Response                    = (1 << 1),
        };

        uint64_t type;
        Flags flags;
        uint32_t tag;

        std::byte payload[];
    };
    static_assert(!(offsetof(MessageHeader, payload) % sizeof(uintptr_t)),
        "message header's payload is not word aligned");

    constexpr static const std::string_view kServiceName{"DiskDriver"};

    protected:
        using IoStream = rt::ServerRpcIoStream;
        // Return types for method 'GetCapacity'
        struct GetCapacityReturn {
            int32_t status;
            uint32_t sectorSize;
            uint64_t numSectors;
        };
        // Return types for method 'OpenSession'
        struct OpenSessionReturn {
            int32_t status;
            uint64_t sessionToken;
            uint64_t regionHandle;
            uint64_t regionSize;
            uint64_t numCommands;
        };
        // Return types for method 'CreateReadBuffer'
        struct CreateReadBufferReturn {
            int32_t status;
            uint64_t readBufHandle;
            uint64_t readBufMaxSize;
        };
        // Return types for method 'CreateWriteBuffer'
        struct CreateWriteBufferReturn {
            int32_t status;
            uint64_t writeBufHandle;
            uint64_t writeBufMaxSize;
        };
        // Return types for method 'AllocWriteMemory'
        struct AllocWriteMemoryReturn {
            int32_t status;
            uint64_t offset;
            uint64_t bytesAllocated;
        };

    public:
        DiskDriverServer(const std::shared_ptr<IoStream> &stream);
        virtual ~DiskDriverServer();

        // Server's main loop; continuously read and handle messages.
        bool run(const bool block = true);
        // Process a single message.
        bool runOne(const bool block);

    // These are methods the implementation provides to complete implementation of the interface
    protected:
        virtual GetCapacityReturn implGetCapacity(uint64_t diskId) = 0;
        virtual OpenSessionReturn implOpenSession() = 0;
        virtual int32_t implCloseSession(uint64_t session) = 0;
        virtual CreateReadBufferReturn implCreateReadBuffer(uint64_t session, uint64_t requestedSize) = 0;
        virtual CreateWriteBufferReturn implCreateWriteBuffer(uint64_t session, uint64_t requestedSize) = 0;
        virtual void implExecuteCommand(uint64_t session, uint32_t slot) = 0;
        virtual void implReleaseReadCommand(uint64_t session, uint32_t slot) = 0;
        virtual AllocWriteMemoryReturn implAllocWriteMemory(uint64_t session, uint64_t bytesRequested) = 0;

    // Helpers provided to subclasses for implementation of interface methods
    protected:
        constexpr inline auto &getIo() {
            return this->io;
        }

        /// Handles errors occurring during server operations
        virtual void _HandleError(const bool fatal, const std::string_view &what);

    // Implementation details; pretend this does not exist
    private:
        std::shared_ptr<IoStream> io;
        size_t txBufSize{0};
        void *txBuf{nullptr};

        void _ensureTxBuf(const size_t);
        void _sendReply(const MessageHeader &, const size_t);

        void _marshallGetCapacity(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallOpenSession(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallCloseSession(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallCreateReadBuffer(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallCreateWriteBuffer(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallExecuteCommand(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallReleaseReadCommand(const MessageHeader &, const std::span<std::byte> &payload);
        void _marshallAllocWriteMemory(const MessageHeader &, const std::span<std::byte> &payload);
}; // class DiskDriverServer
} // namespace rpc
#endif // defined(RPC_SERVER_GENERATED_17065700451208530523)
