# typed: strict
module Scraper::Metrics::HttpClientMetrics
  extend T::Sig

  sig { params(request: Scraper::CurlHttpPerformer::Request).void }
  def self.observe_request_start(request)
    REQUEST_START_COUNTER.increment(
      { method: request.http_method.serialize, host: request.uri.host },
    )
  end

  sig do
    params(
      method: Scraper::CurlHttpPerformer::Method,
      host: String,
      content_type: String,
      status_code: Integer,
      response_time_ms: Integer,
      response_size_bytes: Integer,
    ).void
  end
  def self.observe_request_finish(
    method:,
    host:,
    content_type:,
    status_code:,
    response_time_ms:,
    response_size_bytes:
  )
    keys = {
      method: method.serialize,
      host: host,
      content_type: content_type,
      status_code: status_code,
    }.freeze
    REQUEST_FINISH_COUNTER.increment(keys)
    REQUEST_FINISH_RESPONSE_SIZE_COUNTER.observe(response_size_bytes, keys)
    REQUEST_FINISH_RESPONSE_TIME_HISTOGRAM.observe(response_time_ms, keys)
    REQUEST_FINISH_RESPONSE_SIZE_HISTOGRAM.observe(response_size_bytes, keys)
    REQUEST_FINISH_RESPONSE_TIME_SUMMARY.observe(response_time_ms, keys)
  end

  private

  REQUEST_START_COUNTER =
    T.let(
      PrometheusExporter::Client.default.register(
        :counter,
        "http_client_request_start_counter",
        "http client request started",
      ),
      PrometheusExporter::Client::RemoteMetric,
    )

  REQUEST_FINISH_COUNTER =
    T.let(
      PrometheusExporter::Client.default.register(
        :counter,
        "http_client_request_finish_counter",
        "count of http client requests finished, labeled by their status code and host",
      ),
      PrometheusExporter::Client::RemoteMetric,
    )

  REQUEST_FINISH_RESPONSE_SIZE_COUNTER =
    T.let(
      PrometheusExporter::Client.default.register(
        :counter,
        "http_client_request_finish_response_size_counter",
        "bytes of http client response size, labeled by their status code and host",
      ),
      PrometheusExporter::Client::RemoteMetric,
    )

  REQUEST_FINISH_RESPONSE_TIME_HISTOGRAM =
    T.let(
      PrometheusExporter::Client.default.register(
        :histogram,
        "http_client_request_finish_histogram",
        "histogram of http client request time in ms, labeled by their status code and host",
        buckets: Scraper::Metrics::RESPONSE_TIME_MS_BUCKETS,
      ),
      PrometheusExporter::Client::RemoteMetric,
    )

  REQUEST_FINISH_RESPONSE_TIME_SUMMARY =
    T.let(
      PrometheusExporter::Client.default.register(
        :summary,
        "http_client_request_finish_summary",
        "summary (p99, etc) of http client request time in ms, labeled by their status code and host",
        quantiles: Scraper::Metrics::QUARTILES,
      ),
      PrometheusExporter::Client::RemoteMetric,
    )

  REQUEST_FINISH_RESPONSE_SIZE_HISTOGRAM =
    T.let(
      PrometheusExporter::Client.default.register(
        :histogram,
        "http_client_request_finish_response_size_histogram",
        "histogram of http client response size in bytes, labeled by their status code and host",
        buckets: Scraper::Metrics::FILESIZE_BYTES_BUCKETS,
      ),
      PrometheusExporter::Client::RemoteMetric,
    )
end
