# frozen_string_literal: true

require "rack"

module AppProfiler
  class RequestParameters
    DEFAULT_INTERVALS = { "cpu" => 1000, "wall" => 1000, "object" => 2000 }.freeze
    MIN_INTERVALS = { "cpu" => 200, "wall" => 200, "object" => 400 }.freeze
    MODES = DEFAULT_INTERVALS.keys.freeze

    def initialize(request)
      @request = request
    end

    def autoredirect
      query_param("autoredirect") || profile_header_param("autoredirect")
    end

    def valid?
      if mode.blank?
        return false
      end

      unless MODES.include?(mode)
        AppProfiler.logger.info("[Profiler] unsupported profiling mode=#{mode}")
        return false
      end

      if interval.to_i < MIN_INTERVALS[mode]
        return false
      end

      true
    end

    def to_h
      {
        mode: mode.to_sym,
        interval: interval.to_i,
        metadata: {
          id: request_id,
          context: context,
        },
      }
    end

    private

    def mode
      query_param("profile") || profile_header_param("mode")
    end

    def interval
      query_param("interval") || profile_header_param("interval") || DEFAULT_INTERVALS[mode]
    end

    def request_id
      header("HTTP_X_REQUEST_ID")
    end

    def context
      profile_header_param("context").presence || AppProfiler.context
    end

    def profile_header_param(name)
      query_parser.parse_nested_query(header(profile_header), ";")[name]
    rescue Rack::QueryParser::ParameterTypeError, RangeError
      nil
    end

    def query_param(name)
      @request.GET[name]
    rescue Rack::QueryParser::ParameterTypeError, RangeError
      nil
    end

    def header(name)
      return unless @request.has_header?(name)
      @request.get_header(name)
    end

    def query_parser
      Rack::Utils.default_query_parser
    end

    def profile_header
      AppProfiler.request_profile_header
    end
  end
end
