# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

require 'contrast/utils/input_classification_base'

module Contrast
  module Agent
    module Protect
      module Rule
        # The Ruby implementation of the Protect Reflected XSS rule
        # Input classification
        module ReflectedXssInputClassification
          REFLECTED_XSS_MATCH = 'reflected-xss-input-tracing-v1'.cs__freeze
          WORTHWATCHING_MATCH = 'xss-worth-watching-v2'.cs__freeze
          class << self
            include InputClassificationBase

            private

            # This methods checks if input is tagged WORTHWATCHING or IGNORE matches value with it's
            # key if needed and Creates new isntance of InputAnalysisResult.
            #
            # @param request [Contrast::Agent::Request] the current request context.
            # @param rule_id [String] The name of the Protect Rule.
            # @param input_type [Contrast::Agent::Reporting::InputType] The type of the user input.
            # @param value [String, Array<String>] the value of the input.
            #
            # @return res [Contrast::Agent::Reporting::InputAnalysisResult]
            def create_new_input_result request, rule_id, input_type, value
              return unless Contrast::AGENT_LIB

              input_eval = Contrast::AGENT_LIB.eval_input(value,
                                                          convert_input_type(input_type),
                                                          Contrast::AGENT_LIB.rule_set[rule_id],
                                                          Contrast::AGENT_LIB.
                                                            eval_option[:PREFER_WORTH_WATCHING])

              score = input_eval&.score || 0
              ia_result = new_ia_result(rule_id, input_type, request.path, value)
              if score >= THRESHOLD
                ia_result.score_level = DEFINITEATTACK
                ia_result.ids << REFLECTED_XSS_MATCH
              elsif score >= WORTHWATCHING_THRESHOLD
                ia_result.score_level = WORTHWATCHING
                ia_result.ids << WORTHWATCHING_MATCH
              else
                ia_result.score_level = IGNORE
              end

              add_needed_key(request, ia_result, input_type, value)
              ia_result
            end
          end
        end
      end
    end
  end
end