class ElasticAPM::Spies::NetHTTPSpy

@api private

def disable_in

def disable_in
  self.disabled = true
  begin
    yield
  ensure
    self.disabled = false
  end
end

def disabled=(disabled)

def disabled=(disabled)
  Thread.current[KEY] = disabled
end

def disabled?

def disabled?
  Thread.current[KEY] ||= false
end

def install

rubocop:disable Metrics/CyclomaticComplexity
def install
  Net::HTTP.class_eval do
    alias request_without_apm request
    def request(req, body = nil, &block)
      unless (transaction = ElasticAPM.current_transaction)
        return request_without_apm(req, body, &block)
      end
      if ElasticAPM::Spies::NetHTTPSpy.disabled?
        return request_without_apm(req, body, &block)
      end
      host = req['host']&.split(':')&.first || address
      method = req.method.to_s.upcase
      path, query = req.path.split('?')
      cls = use_ssl? ? URI::HTTPS : URI::HTTP
      uri = cls.build([nil, host, port, path, query, nil])
      destination =
        ElasticAPM::Span::Context::Destination.from_uri(uri)
      context =
        ElasticAPM::Span::Context.new(
          http: { url: uri, method: method },
          destination: destination
        )
      ElasticAPM.with_span(
        "#{method} #{host}",
        TYPE,
        subtype: SUBTYPE,
        action: method,
        context: context
      ) do |span|
        trace_context = span&.trace_context || transaction.trace_context
        trace_context.apply_headers { |key, value| req[key] = value }
        result = request_without_apm(req, body, &block)
        if (http = span&.context&.http)
          http.status_code = result.code
        end
        result
      end
    end
  end
end

def request(req, body = nil, &block)

def request(req, body = nil, &block)
  unless (transaction = ElasticAPM.current_transaction)
    return request_without_apm(req, body, &block)
  end
  if ElasticAPM::Spies::NetHTTPSpy.disabled?
    return request_without_apm(req, body, &block)
  end
  host = req['host']&.split(':')&.first || address
  method = req.method.to_s.upcase
  path, query = req.path.split('?')
  cls = use_ssl? ? URI::HTTPS : URI::HTTP
  uri = cls.build([nil, host, port, path, query, nil])
  destination =
    ElasticAPM::Span::Context::Destination.from_uri(uri)
  context =
    ElasticAPM::Span::Context.new(
      http: { url: uri, method: method },
      destination: destination
    )
  ElasticAPM.with_span(
    "#{method} #{host}",
    TYPE,
    subtype: SUBTYPE,
    action: method,
    context: context
  ) do |span|
    trace_context = span&.trace_context || transaction.trace_context
    trace_context.apply_headers { |key, value| req[key] = value }
    result = request_without_apm(req, body, &block)
    if (http = span&.context&.http)
      http.status_code = result.code
    end
    result
  end
end