/*
 *  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 <functional>
#include <vector>
#include <chrono>
#include <system_error>
#include <cstdint>

#if defined(_MSC_VER)
#include <BaseTsd.h>
using ssize_t = SSIZE_T;
#endif

namespace dhtnet {

template<typename T>
class GenericSocket
{
public:
    using ValueType = T;

    virtual ~GenericSocket() { shutdown(); }

    using RecvCb = std::function<ssize_t(const ValueType* buf, std::size_t len)>;

    /// Close established connection
    /// \note Terminate outstanding blocking read operations with an empty error code, but a 0 read size.
    virtual void shutdown() {}

    /// Set Rx callback
    /// \warning This method is here for backward compatibility
    /// and because async IO are not implemented yet.
    virtual void setOnRecv(RecvCb&& cb) = 0;

    virtual bool isReliable() const = 0;

    virtual bool isInitiator() const = 0;

    /// Return maximum application payload size.
    /// This value is negative if the session is not ready to give a valid answer.
    /// The value is 0 if such information is irrelevant for the session.
    /// If stricly positive, the user must use send() with an input buffer size below or equals
    /// to this value if it want to be sure that the transport sent it in an atomic way.
    /// Example: in case of non-reliable transport using packet oriented IO,
    /// this value gives the maximal size used to send one packet.
    virtual int maxPayload() const = 0;

    /// Wait until data to read available, timeout or io error
    /// \param ec error code set in case of error (if return value is < 0)
    /// \return positive number if data ready for read, 0 in case of timeout or error.
    /// \note error code is not set in case of timeout, but set only in case of io error
    /// (i.e. socket deconnection).
    /// \todo make a std::chrono version for the timeout
    virtual int waitForData(std::chrono::milliseconds timeout, std::error_code& ec) const = 0;

    /// Write a given amount of data.
    /// \param buf data to write.
    /// \param len number of bytes to write.
    /// \param ec error code set in case of error.
    /// \return number of bytes written, 0 is valid.
    /// \warning error checking consists in checking if \a !ec is true, not if returned size is 0
    /// as a write of 0 could be considered a valid operation.
    virtual std::size_t write(const ValueType* buf, std::size_t len, std::error_code& ec) = 0;

    /// Read a given amount of data.
    /// \param buf data to read.
    /// \param len number of bytes to read.
    /// \param ec error code set in case of error.
    /// \return number of bytes read, 0 is valid.
    /// \warning error checking consists in checking if \a !ec is true, not if returned size is 0
    /// as a read of 0 could be considered a valid operation (i.e. non-blocking IO).
    virtual std::size_t read(ValueType* buf, std::size_t len, std::error_code& ec) = 0;

    /// write() adaptor for STL containers
    template<typename U>
    std::size_t write(const U& obj, std::error_code& ec)
    {
        return write(obj.data(), obj.size() * sizeof(typename U::value_type), ec);
    }

    /// read() adaptor for STL containers
    template<typename U>
    std::size_t read(U& storage, std::error_code& ec)
    {
        auto res = read(storage.data(), storage.size() * sizeof(typename U::value_type), ec);
        if (!ec)
            storage.resize(res);
        return res;
    }

    /// Return the local IP address if known.
    /// \note The address is not valid (addr.isUnspecified() returns true) if it's not known
    /// or not available.
    virtual IpAddr localAddr() const { return {}; }

    /// Return the remote IP address if known.
    /// \note The address is not valid (addr.isUnspecified() returns true) if it's not known
    /// or not available.
    virtual IpAddr remoteAddr() const { return {}; }

protected:
    GenericSocket() = default;
};

} // namespace dhtnet
