// SPDX-License-Identifier: GPL-2.0-only
/*
 * Digital Voice Modem - Converged FNE Software
 * GPLv2 Open Source. Use is subject to license terms.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 *  Copyright (C) 2024 Bryan Biedenkapp, N2PLL
 *
 */
/**
 * @file MetadataNetwork.h
 * @ingroup fne_network
 * @file MetadataNetwork.cpp
 * @ingroup fne_network
 */
#if !defined(__METADATA_NETWORK_H__)
#define __METADATA_NETWORK_H__

#include "fne/Defines.h"
#include "common/network/BaseNetwork.h"
#include "common/ThreadPool.h"
#include "fne/network/TrafficNetwork.h"

#include <string>

// ---------------------------------------------------------------------------
//  Class Prototypes
// ---------------------------------------------------------------------------

class HOST_SW_API HostFNE;

namespace network
{
    // ---------------------------------------------------------------------------
    //  Class Declaration
    // ---------------------------------------------------------------------------

    /**
     * @brief Implements the diagnostic/activity log networking logic.
     * @ingroup fne_network
     */
    class HOST_SW_API MetadataNetwork : public BaseNetwork {
    public:
        /**
         * @brief Initializes a new instance of the MetadataNetwork class.
         * @param host Instance of the HostFNE class.
         * @param network Instance of the TrafficNetwork class.
         * @param address Network Hostname/IP address to listen on.
         * @param port Network port number.
         * @param workerCnt Number of worker threads.
         */
        MetadataNetwork(HostFNE* host, TrafficNetwork* trafficNetwork, const std::string& address, uint16_t port, uint16_t workerCnt);
        /**
         * @brief Finalizes a instance of the MetadataNetwork class.
         */
        ~MetadataNetwork() override;

        /**
         * @brief Gets the current status of the network.
         * @returns NET_CONN_STATUS Current network status.
         */
        NET_CONN_STATUS getStatus() { return m_status; }

        /**
         * @brief Sets endpoint preshared encryption key.
         * @param presharedKey Encryption preshared key for networking.
         */
        void setPresharedKey(const uint8_t* presharedKey);

        /**
         * @brief Process a data frames from the network.
         */
        void processNetwork();

        /**
         * @brief Updates the timer by the passed number of milliseconds.
         * @param ms Number of milliseconds.
         */
        void clock(uint32_t ms) override;

        /**
         * @brief Opens connection to the network.
         * @returns bool True, if networking has started, otherwise false.
         */
        bool open() override;

        /**
         * @brief Closes connection to the network.
         */
        void close() override;

    private:
        friend class TrafficNetwork;
        TrafficNetwork* m_trafficNetwork;
        HostFNE* m_host;

        std::string m_address;
        uint16_t m_port;

        NET_CONN_STATUS m_status;

        /**
         * @brief Represents a packet buffer entry in a map.
         */
        class PacketBufferEntry {
        public:
            /**
             * @brief Stream ID of the packet.
             */
            uint32_t streamId;

            /**
             * @brief Packet fragment buffer.
             */
            PacketBuffer* buffer;

            bool locked;
            uint32_t timeout;
        };
        concurrent::unordered_map<uint32_t, PacketBufferEntry> m_peerKeyUpdatePkt;
        concurrent::unordered_map<uint32_t, PacketBufferEntry> m_peerReplicaActPkt;
        concurrent::unordered_map<uint32_t, PacketBufferEntry> m_peerTreeListPkt;

        ThreadPool m_threadPool;

        /**
         * @brief Entry point to process a given network packet.
         * @param req Instance of the NetPacketRequest structure.
         */
        static void taskNetworkRx(NetPacketRequest* req);
    };
} // namespace network

#endif // __METADATA_NETWORK_H__
