#pragma once
#include <string>

namespace detail {
template <class... Fs>
struct overload;

template <class F>
struct overload<F> : public F {
  explicit overload(F f) : F(f) {
  }
};
template <class F, class... Fs>
struct overload<F, Fs...>
    : public overload<F>
    , public overload<Fs...> {
  overload(F f, Fs... fs) : overload<F>(f), overload<Fs...>(fs...) {
  }
  using overload<F>::operator();
  using overload<Fs...>::operator();
};
}  // namespace detail

template <class... F>
auto overloaded(F... f) {
  return detail::overload<F...>(f...);
}


enum class CommandLineParamError {
  NoApiCreds
};

struct ApiCreds {
  int id;
  std::string hash;
  std::string botToken;
};

struct CommandLineParams {
  ApiCreds apiCreds;
  std::string botToken;
};

struct TelegramClient;

struct context {
  TelegramClient *tg;
  ApiCreds apiCreds;
};