#pragma once

#include <functional>
#include <string>

namespace mtran
{

enum class ClientError
{
  kNone,
  kUnavailable,
  kTimeout,
  kUpstream,
  kInvalidResponse,
};

struct TranslationResult
{
  bool success;
  std::string translation;
  ClientError error;
};

struct HttpResponse
{
  int transport_code;
  long status_code;
  std::string body;
};

using HttpExecutor = std::function<HttpResponse(
      const std::string & method,
      const std::string & url,
      const std::string & body,
      long timeout_ms)>;

class TranslationClient
{
public:
  virtual ~TranslationClient() = default;

  virtual bool health() = 0;
  virtual TranslationResult translate(const std::string & text) = 0;
};

class HttpTranslationClient final : public TranslationClient
{
public:
  HttpTranslationClient(
    std::string server_url,
    long timeout_ms,
    HttpExecutor executor = {});

  bool health() override;
  TranslationResult translate(const std::string & text) override;

private:
  static HttpResponse execute_with_curl(
    const std::string & method,
    const std::string & url,
    const std::string & body,
    long timeout_ms);

  std::string server_url_;
  long timeout_ms_;
  HttpExecutor executor_;
};

}  // namespace mtran
