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

require 'contrast/utils/object_share'
require 'contrast/utils/duck_utils'
require 'contrast/agent/reporting/input_analysis/input_analysis_result'

module Contrast
  module Agent
    module Reporting
      # This class will do ia analysis for our protect rules
      class InputAnalysis
        # @return [Hash] Stored request inputs for this context.
        attr_accessor :inputs

        # Records rules triggered on sink.
        #
        # @return [Array<String>] array with rule names.
        def triggered_rules
          @_triggered_rules ||= []
        end

        # Records rules with input analysis for current request.
        #
        # @return [Array<String>] array with rule names.
        def analysed_rules
          @_analysed_rules ||= []
        end

        # result from input analysis
        #
        # @return @_results [Array<Contrast::Agent::Reporting::Settings::InputAnalysisResult>]
        def results
          @_results ||= []
        end

        # result from input analysis
        #
        # @return @_results [Array<Contrast::Agent::Reporting::Settings::InputAnalysisResult>]
        def results= results
          @_results = results
        end

        # Returns our wrapper around the Rack::Request for this context
        #
        # @return request [Contrast::Agent::Request, nil]
        def request
          @_request ||= nil
        end

        # Sets current request
        #
        # @param request [Contrast::Agent::Request] our wrapper around the Rack::Request for this context
        # @return request [Contrast::Agent::Request, nil]
        def request= request
          @_request = request if request.instance_of?(Contrast::Agent::Request)
        end

        # Check if the InputAnalysis is empty.
        def no_inputs?
          Contrast::Utils::DuckUtils.empty_duck?(inputs)
        end

        # We add the analysed rules to the list. The IA won't be build for this rule,
        # since already it's already available.
        #
        # @param rule_name [String] name to record.
        def record_analysed_rule rule_name
          analysed_rules << rule_name unless triggered_rules.include?(rule_name)
        end

        # We add the triggered rules to the list. After request analysis will skip this rule
        # as already triggered.
        #
        # @param rule_name [String] name to record.
        def record_rule_triggered rule_name
          triggered_rules << rule_name unless triggered_rules.include?(rule_name)
        end
      end
    end
  end
end