class JSONAPI::Rack::QueryTracking

def add_jpie_headers(headers)

def add_jpie_headers(headers)
  tracking = Thread.current[:jpie_query_tracking]
  return if tracking.nil?
  count = tracking[:count]
  headers["X-JPie-Query-Count"] = count.to_s
  warning_str = build_performance_warning_header(count)
  headers["X-JPie-Performance-Warning"] = warning_str if warning_str.present?
end

def build_excessive_queries_payload(env, count, threshold, queries)

def build_excessive_queries_payload(env, count, threshold, queries)
  build_payload(env).merge(
    query_count: count,
    threshold: threshold,
    queries: queries,
  )
end

def build_payload(env)

def build_payload(env)
  base = env.nil? ? {} : request_payload_from_env(env)
  base.merge(correlation_id: JSONAPI::Support::CorrelationId.resolve)
end

def build_performance_warning_header(count)

def build_performance_warning_header(count)
  warnings = (Thread.current[:jpie_warnings] || []).dup
  warnings << "excessive_queries" if count > JSONAPI.configuration.query_count_threshold
  warnings.uniq.join(",").presence
end

def call(env)

def call(env)
  return @app.call(env) unless JSONAPI.configuration.query_tracking_enabled
  return @app.call(env) unless jsonapi_request?(env)
  call_with_tracking(env)
ensure
  emit_excessive_queries_if_needed
  Thread.current[:jpie_query_tracking] = nil
  Thread.current[:jpie_warnings] = nil
end

def call_with_tracking(env)

def call_with_tracking(env)
  Thread.current[:jpie_query_tracking] = { count: 0, queries: [], env: env }
  Thread.current[:jpie_warnings] = [] if JSONAPI.configuration.jpie_headers_enabled
  status, headers, body = @app.call(env)
  add_jpie_headers(headers) if JSONAPI.configuration.jpie_headers_enabled
  [status, headers, body]
end

def emit_excessive_queries_if_needed

def emit_excessive_queries_if_needed
  tracking = Thread.current[:jpie_query_tracking]
  return if tracking.nil?
  count = tracking[:count]
  threshold = JSONAPI.configuration.query_count_threshold
  return if count <= threshold
  return unless defined?(Rails) && Rails.respond_to?(:event)
  notify_excessive_queries(tracking, count, threshold)
end

def initialize(app)

def initialize(app)
  @app = app
end

def jsonapi_request?(env)

def jsonapi_request?(env)
  env["HTTP_ACCEPT"].to_s.include?("application/vnd.api+json")
end

def notify_excessive_queries(tracking, count, threshold)

def notify_excessive_queries(tracking, count, threshold)
  cap = JSONAPI.configuration.query_tracking_queries_cap
  queries = tracking[:queries].first(cap)
  payload = build_excessive_queries_payload(tracking[:env], count, threshold, queries)
  Rails.event.tagged("jsonapi", "excessive_queries") do
    Rails.event.notify("jpie.excessive_queries_detected", payload)
  end
end

def request_payload_from_env(env)

def request_payload_from_env(env)
  req = ActionDispatch::Request.new(env)
  params = req.params
  {
    path: req.path,
    method: req.request_method,
    include: params[:include],
    resource_type: params[:resource_type],
    resource_id: params[:id],
  }
end