require "net/http"
require "uri"
require_relative "result"

module Relay
  # The single place outbound HTTP happens. Timeouts, TLS policy, and
  # instrumentation live here so call sites cannot drift.
  class HttpClient
    OPEN_TIMEOUT = 5
    READ_TIMEOUT = 5

    def post(url, body, headers = {})
      uri = URI.parse(url)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = uri.scheme == "https"
      http.open_timeout = OPEN_TIMEOUT
      http.read_timeout = READ_TIMEOUT

      request = Net::HTTP::Post.new(uri.request_uri, default_headers.merge(headers))
      request.body = body
      response = http.request(request)

      if response.is_a?(Net::HTTPSuccess)
        Result.ok(response)
      else
        Result.err("HTTP #{response.code} from #{uri.host}")
      end
    rescue SystemCallError, Net::OpenTimeout, Net::ReadTimeout => e
      Result.err("#{e.class}: #{e.message}")
    end

    private

    def default_headers
      { "Content-Type" => "application/json", "User-Agent" => "relay/1.0" }
    end
  end
end
