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

module Contrast
  module Agent
    module Reporting
      module Settings
        # Base class to represent common exclusions fields.
        class ExclusionBase
          BASE_ATTRIBUTES = %i[name modes assess_rules protect_rules urls match_strategy].cs__freeze
          STRATEGIES = %w[ALL ONLY].cs__freeze

          # Base attribute for exclusion name.
          # For ng response it corresponds only for the name of the exclusion,
          # in the new server settings endpoint it is used to store the name
          # of the input to be excluded.
          #
          # @return name [String]
          attr_accessor :name
          # @return modes [Array<String>]
          attr_accessor :modes
          # @return urls [Array<String>]
          attr_accessor :urls

          def initialize
            @modes = []
            @urls = []
          end

          # @return match_strategy [String] The type of the input.
          def match_strategy
            @_match_strategy ||= Contrast::Utils::ObjectShare::EMPTY_STRING
          end

          # @param new_strategy [String] Set new input type.
          # @return type [String] The type of the input.
          def match_strategy= new_strategy
            @_match_strategy = new_strategy if STRATEGIES.include?(new_strategy)
          end

          # @return [Boolean] does this exclusion apply to Assess or not.
          def assess
            @_assess = modes&.include?('assess') if @_assess.nil?
            @_assess
          end

          # @return [Boolean] does this exclusion apply to Protect or not.
          def protect
            @_protect = modes&.include?('defend') if @_protect.nil?
            @_protect
          end

          # Array of all excluded protect rules.
          #
          # @return [Array<String>]
          def protect_rules
            @_protect_rules ||= rules
          end

          # Setter for protect rules array.
          #
          # @param new_rules [Array<String>]
          # @return [Array<String>]
          def protect_rules= new_rules
            @_protect_rules = new_rules if new_rules.cs__is_a?(Array)
          end

          # Array of all excluded assess rules.
          #
          # @return [Array<String>]
          def assess_rules
            @_assess_rules ||= assessment_rules
          end

          # Setter for assess rules array.
          #
          # @param new_rules [Array<String>]
          # @return [Array<String>]
          def assess_rules= new_rules
            @_assess_rules = new_rules if new_rules.cs__is_a?(Array)
          end

          def to_controlled_hash
            {
                name: name, # rubocop:disable Security/Module/Name
                modes: modes,
                urls: urls,
                assess_rules: assess_rules,
                protect_rules: protect_rules,
                match_strategy: match_strategy
            }
          end

          private

          # Private getter for assess_rules used with application create response parsing.
          #
          # @return [Array<String>]
          def assessment_rules
            @_assessment_rules ||= []
          end

          # Private setter for assess_rules used with application create response parsing.
          #
          # @param new_rules [Array<String>]
          # @return [Array<String>]
          def assessment_rules= new_rules
            @_assessment_rules = new_rules if new_rules.cs__is_a?(Array)
          end

          # Private getter for protect rules used with application create response parsing.
          #
          # @return [Array<String>]
          def rules
            @_rules ||= []
          end

          # Private setter for protect rules used with application create response parsing.
          #
          # @param new_rules [Array<String>]
          # @return [Array<String>]
          def rules= new_rules
            @_rules = new_rules if new_rules.cs__is_a?(Array)
          end
        end
      end
    end
  end
end