/*
 *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
#pragma once

#include "../ip_utils.h"

#include "mapping.h"

#include <opendht/rng.h>
#include <opendht/logger.h>
#include <asio/steady_timer.hpp>
#include <asio/system_timer.hpp>

#include <set>
#include <map>
#include <mutex>
#include <memory>
#include <string>
#include <chrono>
#include <random>
#include <atomic>
#include <condition_variable>

#include <cstdlib>

using IgdFoundCallback = std::function<void()>;

namespace dhtnet {
class IpAddr;
}

namespace dhtnet {
namespace upnp {

class UPnPProtocol;
class IGD;

struct IGDInfo
{
    std::string uid;
    IpAddr localIp;
    IpAddr publicIp;
    std::vector<MappingInfo> mappingInfoList;
};

enum class UpnpIgdEvent { ADDED, REMOVED, INVALID_STATE };

// Interface used to report mapping event from the protocol implementations.
// This interface is meant to be implemented only by UPnPContext class. Since
// this class is a singleton, it's assumed that it outlives the protocol
// implementations. In other words, the observer is always assumed to point to a
// valid instance.
class UpnpMappingObserver
{
public:
    UpnpMappingObserver() {};
    virtual ~UpnpMappingObserver() {};

    virtual void onIgdUpdated(const std::shared_ptr<IGD>& igd, UpnpIgdEvent event) = 0;
    virtual void onMappingAdded(const std::shared_ptr<IGD>& igd, const Mapping& map) = 0;
    virtual void onMappingRequestFailed(const Mapping& map) = 0;
    virtual void onMappingRenewed(const std::shared_ptr<IGD>& igd, const Mapping& map) = 0;
    virtual void onMappingRemoved(const std::shared_ptr<IGD>& igd, const Mapping& map) = 0;
    virtual void onIgdDiscoveryStarted() = 0;
};

class UPnPContext : public UpnpMappingObserver
{
public:
    UPnPContext(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger);
    ~UPnPContext();

    std::shared_ptr<asio::io_context> createIoContext(const std::shared_ptr<asio::io_context>& ctx, const std::shared_ptr<dht::log::Logger>& logger);

    // Terminate the instance.
    void shutdown();

    // Set the known public address
    void setPublicAddress(const IpAddr& addr);

    // Check if there is a valid IGD in the IGD list.
    bool isReady() const;

    // Get external Ip of a chosen IGD.
    IpAddr getExternalIP() const;

    // Inform the UPnP context that the network status has changed.
    void connectivityChanged();

    // Returns a shared pointer of the mapping.
    Mapping::sharedPtr_t reserveMapping(Mapping& requestedMap);

    // Release a used mapping (make it available for future use).
    void releaseMapping(const Mapping& map);

    // Register a controller
    void registerController(void* controller);
    // Unregister a controller
    void unregisterController(void* controller);

    // Generate random port numbers
    static uint16_t generateRandomPort(PortType type);

    // Return information about the UPnPContext's valid IGDs, including the list
    // of all existing port mappings (for IGDs which support a protocol that allows
    // querying that information -- UPnP does, but NAT-PMP doesn't for example)
    std::vector<IGDInfo> getIgdsInfo() const;

    template <typename T>
    inline void dispatch(T&& f) {
        ctx->dispatch(std::move(f));
    }

    void restart()
    {
        ctx->dispatch([this]{
            stopUpnp();
            startUpnp();
        });
    }

    // Set the timeout for the IGD discovery process.
    // If the timeout expires and no valid IGD has been discovered,
    // then the state of all pending mappings is set to FAILED.
    void setIgdDiscoveryTimeout(std::chrono::milliseconds timeout);

private:
    // Initialization
    void init();

    /**
     * @brief start the search for IGDs activate the mapping
     * list update.
     *
     */
    void startUpnp();

    /**
     * @brief Clear all IGDs and release/delete current mappings
     *
     * @param forceRelease If true, also delete mappings with enabled
     * auto-update feature.
     *
     */
    void stopUpnp(bool forceRelease = false);

    void shutdown(std::condition_variable& cv);

    // Add a new mapping to the local list and
    // send a request to the IGD to create it.
    Mapping::sharedPtr_t registerMapping(Mapping& map);

    // Remove the given mapping from the local list.
    void unregisterMapping(const Mapping::sharedPtr_t& map);

    // Perform the request on the provided IGD.
    void requestMapping(const Mapping::sharedPtr_t& map);

    // Request a mapping remove from the IGD.
    void requestRemoveMapping(const Mapping::sharedPtr_t& map);

    // Update the state and notify the listener
    void updateMappingState(const Mapping::sharedPtr_t& map,
                            MappingState newState,
                            bool notify = true);

    // Provision ports.
    uint16_t getAvailablePortNumber(PortType type);

    // If the current IGD is still valid, do nothing.
    // If not, then replace it with a valid one (if possible) or set it to null.
    void updateCurrentIgd();

    // Get the current IGD
    std::shared_ptr<IGD> getCurrentIgd() const;

    // Send a renewal request to the IGD for each mapping which is past its renewal time.
    void renewMappings();

    // Set a timer so that renewMappings is called when needed
    void scheduleMappingsRenewal();
    void _scheduleMappingsRenewal();

    // Add or remove mappings to maintain the number of available mappings
    // within the limits set by minAvailableMappings_ and maxAvailableMappings_.
    void enforceAvailableMappingsLimits();

    // Provision (pre-allocate) the requested number of mappings.
    void provisionNewMappings(PortType type, int portCount);

    // Close unused mappings.
    void deleteUnneededMappings(PortType type, int portCount);

    // Get information from the current IGD about the mappings it currently has
    // and update the local list accordingly. (Only called if the current IGD
    // uses the UPnP protocol -- NAT-PMP doesn't support doing this.)
    void syncLocalMappingListWithIgd();
    void _syncLocalMappingListWithIgd();

    void pruneMappingsWithInvalidIgds(const std::shared_ptr<IGD>& igd);

    /**
     * @brief Get the mapping list
     *
     * @param type transport type (TCP/UDP)
     * @return a reference on the map
     * @warning concurrency protection done by the caller
     */
    std::map<Mapping::key_t, Mapping::sharedPtr_t>& getMappingList(PortType type);

    // Get the mapping from the key.
    Mapping::sharedPtr_t getMappingWithKey(Mapping::key_t key);

    // Process requests with pending status.
    void processPendingRequests();

    // Handle mapping with FAILED state.
    //
    // There are two cases to consider: when auto-update is enabled and when it is not.
    // If auto-update is disabled, the mapping will be unregistered.
    // If auto-update is enabled, a new mapping of the same type will be requested if there is a valid IGD available.
    // Otherwise, the mapping request will be marked as pending and will be requested when an IGD becomes available.
    void handleFailedMapping(const Mapping::sharedPtr_t& map);

    // Implementation of UpnpMappingObserver interface.

    // Callback used to report changes in IGD status.
    void onIgdUpdated(const std::shared_ptr<IGD>& igd, UpnpIgdEvent event) override;
    // Callback used to report add request status.
    void onMappingAdded(const std::shared_ptr<IGD>& igd, const Mapping& map) override;
    // Callback invoked when a request fails. Reported on failures for both
    // new requests and renewal requests.
    void onMappingRequestFailed(const Mapping& map) override;

    // Callback used to report renew request status.
    void onMappingRenewed(const std::shared_ptr<IGD>& igd, const Mapping& map) override;

    // Callback used to report remove request status.
    void onMappingRemoved(const std::shared_ptr<IGD>& igd, const Mapping& map) override;

    // Callback used to report the start of the discovery process: search for IGDs.
    void onIgdDiscoveryStarted() override;

private:
    UPnPContext(const UPnPContext&) = delete;
    UPnPContext(UPnPContext&&) = delete;
    UPnPContext& operator=(UPnPContext&&) = delete;
    UPnPContext& operator=(const UPnPContext&) = delete;

    void _connectivityChanged(const asio::error_code& ec);

    // Thread (io_context), destroyed last
    std::unique_ptr<std::thread> ioContextRunner_ {};

    bool started_ {false};

    // The known public address. The external addresses returned by
    // the IGDs will be checked against this address.
    IpAddr knownPublicAddress_ {};
    std::mutex publicAddressMutex_;

    // Map of available protocols.
    std::map<NatProtocolType, std::shared_ptr<UPnPProtocol>> protocolList_;

    // Port ranges for TCP and UDP (in that order).
    std::map<PortType, std::pair<uint16_t, uint16_t>> portRange_ {};

    // Minimum and maximum limits on the number of available
    // mappings to keep in the list at any given time
    static constexpr unsigned minAvailableMappings_[2] {4, 8};
    static constexpr unsigned maxAvailableMappings_[2] {8, 12};
    unsigned getMinAvailableMappings(PortType type) {
        unsigned index = (type == PortType::TCP) ? 0 : 1;
        return minAvailableMappings_[index];
    }
    unsigned getMaxAvailableMappings(PortType type) {
        unsigned index = (type == PortType::TCP) ? 0 : 1;
        return maxAvailableMappings_[index];
    }

    std::shared_ptr<asio::io_context> ctx;
    std::shared_ptr<dht::log::Logger> logger_;
    asio::steady_timer connectivityChangedTimer_;
    asio::system_timer mappingRenewalTimer_;
    asio::steady_timer renewalSchedulingTimer_;
    asio::steady_timer syncTimer_;
    std::mutex syncMutex_;
    bool syncRequested_ {false};

    // This mutex must lock only the members below. All other
    // members must be accessed only from the UPnP context thread.
    std::mutex mutable mappingMutex_;

    // List of mappings.
    std::map<Mapping::key_t, Mapping::sharedPtr_t> mappingList_[2] {};

    // Current IGD. Can be null if there is no valid IGD.
    std::shared_ptr<IGD> currentIgd_;

    // Set of registered controllers
    std::set<void*> controllerList_;

    // Shutdown synchronization
    bool shutdownComplete_ {false};
    bool shutdownTimedOut_ {false};

    // IGD Discovery synchronization. This boolean indicates if the IGD discovery is in progress.
    bool igdDiscoveryInProgress_ {true};
    std::mutex igdDiscoveryMutex_;
    std::chrono::milliseconds igdDiscoveryTimeout_ {std::chrono::milliseconds(500)};

    // End of the discovery process.
    void _endIgdDiscovery();

    asio::steady_timer igdDiscoveryTimer_;
};

} // namespace upnp
} // namespace dhtnet
