#pragma once

#include <Core/Common/NonCopyable.h>
#include <Core/Networking/SocketHandle.h>

namespace Juliet
{
    class Socket : NonCopyable
    {
      public:
        ~Socket() override;

        Socket(Socket&& other) noexcept;
        Socket& operator=(Socket&& socket) noexcept;

        Socket(const Socket&) = delete;
        Socket& operator=(const Socket&) = delete;

        bool IsValid() const;

        enum class Status : uint8
        {
            Done,
            Partial,
            Ready,
            NotReady,
            Disconnected,
            Error
        };

      protected:
        enum class Protocol : uint8
        {
            TCP,
            UDP
        };

        // To store the result of a send/receive on the socket
        struct RequestStatus
        {
            Status Status = Status::Done;
            size_t Length = 0;
        };

        explicit Socket(Protocol protocol);

        SocketHandle GetHandle() const { return Handle; }

        void Create();
        void CreateFromHandle(SocketHandle handle);
        void Close();

      private:
        SocketHandle Handle;
        Protocol     ProtocolType;
    };
} // namespace Juliet
