module Datadog::Tracing::Contrib::Httprb::Instrumentation::InstanceMethods

def analytics_enabled?(request_options)

def analytics_enabled?(request_options)
  Contrib::Analytics.enabled?(request_options[:analytics_enabled])
end

def annotate_span_with_error!(span, error)

def annotate_span_with_error!(span, error)
  span.set_error(error)
end

def annotate_span_with_request!(span, req, req_options)

def annotate_span_with_request!(span, req, req_options)
  span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
  if req_options[:peer_service]
    span.set_tag(
      Tracing::Metadata::Ext::TAG_PEER_SERVICE,
      req_options[:peer_service]
    )
  end
  # Tag original global service name if not used
  if span.service != Datadog.configuration.service
    span.set_tag(Tracing::Contrib::Ext::Metadata::TAG_BASE_SERVICE, Datadog.configuration.service)
  end
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
  if req.verb && req.verb.is_a?(String) || req.verb.is_a?(Symbol)
    http_method = req.verb.to_s.upcase
    span.resource = http_method
    span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, http_method)
  else
    logger.debug("service #{req_options[:service_name]} span #{Ext::SPAN_REQUEST} missing request verb")
  end
  if req.uri
    uri = req.uri
    span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, uri.path)
    span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, uri.host)
    span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, uri.port)
    span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, uri.host)
  else
    logger.debug("service #{req_options[:service_name]} span #{Ext::SPAN_REQUEST} missing uri")
  end
  set_analytics_sample_rate(span, req_options)
  span.set_tags(
    Datadog.configuration.tracing.header_tags.request_tags(req.headers)
  )
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
end

def annotate_span_with_response!(span, response, request_options)

def annotate_span_with_response!(span, response, request_options)
  return unless response && response.code
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.code)
  if request_options[:error_status_codes].include? response.code.to_i
    # https://github.com/DataDog/dd-trace-rb/issues/1116
    # parsing the response body message will alter downstream application behavior
    span.set_error(["Error #{response.code}", 'Error'])
  end
  span.set_tags(
    Datadog.configuration.tracing.header_tags.response_tags(response.headers)
  )
end

def datadog_configuration(host = :default)

def datadog_configuration(host = :default)
  Datadog.configuration.tracing[:httprb, host]
end

def logger

def logger
  Datadog.logger
end

def perform(req, options)

def perform(req, options)
  host = req.uri.host if req.respond_to?(:uri) && req.uri
  request_options = datadog_configuration(host)
  client_config = Datadog.configuration_for(self)
  Tracing.trace(Ext::SPAN_REQUEST, on_error: method(:annotate_span_with_error!)) do |span, trace|
    begin
      span.service = service_name(host, request_options, client_config)
      span.span_type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
      if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
        Tracing::Propagation::HTTP.inject!(trace, req)
      end
      # Add additional request specific tags to the span.
      annotate_span_with_request!(span, req, request_options)
    rescue StandardError => e
      logger.error("error preparing span for http.rb request: #{e}, Source: #{e.backtrace}")
    ensure
      res = super(req, options)
    end
    # Add additional response specific tags to the span.
    annotate_span_with_response!(span, res, request_options)
    res
  end
end

def set_analytics_sample_rate(span, request_options)

def set_analytics_sample_rate(span, request_options)
  return unless analytics_enabled?(request_options)
  Contrib::Analytics.set_sample_rate(span, request_options[:analytics_sample_rate])
end

def should_skip_distributed_tracing?(client_config)

def should_skip_distributed_tracing?(client_config)
  return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
  !Datadog.configuration.tracing[:httprb][:distributed_tracing]
end