BareGit
#pragma once

#include <cstdint>
#include <string>

#include <nlohmann/json.hpp>
#include <mw/error.hpp>

namespace telegrammer
{

using json = nlohmann::json;

/// Abstracts the Telegram operations consumed by the daemon.
class TelegramApi
{
public:
    /// Destroy an API implementation through its interface.
    virtual ~TelegramApi() = default;

    /// Validate the token and return the bot identity envelope.
    virtual mw::E<json> getMe() const = 0;

    /// Send one text message and return Telegram's successful envelope.
    virtual mw::E<json> sendMessage(int64_t chat_id,
                                     const std::string& text) const = 0;

    /// Long-poll Telegram for message updates.
    virtual mw::E<json> getUpdates(int64_t offset, int timeout) const = 0;
};

/// Provides the production HTTPS implementation of the Telegram API.
class TelegramClient final : public TelegramApi
{
public:
    /// Construct a client for one bot token.
    explicit TelegramClient(std::string token);

    /// Validate the token and return the bot identity envelope.
    mw::E<json> getMe() const override;

    /// Send one text message and return Telegram's successful envelope.
    mw::E<json> sendMessage(int64_t chat_id,
                            const std::string& text) const override;

    /// Long-poll Telegram for message updates.
    mw::E<json> getUpdates(int64_t offset, int timeout) const override;

private:
    std::string token_;
    std::string base_url_;

    mw::E<json> request(const std::string& method,
                       const std::string& payload,
                       bool post) const;
};

} // namespace telegrammer