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

require 'contrast/utils/object_share'

module Contrast
  module Agent
    module Reporting
      # This module will hold all the settings from the TS responce
      module Settings
        # Application level settings for the Protect featureset
        class Protect
          # block at perimeter needs to be check against the blockAtEntry boolean value
          PROTECT_RULES_MODE = %w[OFF BLOCKING MONITORING].cs__freeze
          # The settings for each protect rule for this application
          #
          # @return protection_rules [Array<protectRule>] protectRule: {
          #   blockAtEntry [Boolean] If in block mode, to block at perimeter or not.
          #   id           [String] The id of a rule in Contrast.
          #   mode         [String] The mode that this rule should run in. [OFF, MONITORING, BLOCKING] }
          def protection_rules
            @_protection_rules ||= []
          end

          # Set the protection_rules array
          #
          # @param protection_rules [Array<protectRule>] protectRule: {
          #   blockAtEntry [Boolean] If in block mode, to block at perimeter or not.
          #   id           [String] The id of a rule in Contrast.
          #   mode         [String] The mode that this rule should run in. [OFF, MONITORING, BLOCKING] }
          # @return protection_rules [Array<protectRule>] protectRule: {
          #   blockAtEntry [Boolean] If in block mode, to block at perimeter or not.
          #   id           [String] The id of a rule in Contrast.
          #   mode         [String] The mode that this rule should run in. [OFF, MONITORING, BLOCKING] }
          def protection_rules= protection_rules
            @_protection_rules = protection_rules if protection_rules.is_a? Array
          end

          # The virtual patches to apply for this application
          #
          # @return virtual_patches [Array<VirtualPatch>] Array of VirtualPatch: {
          #   name       [String] The name of the Virtual Patch
          #   headers    [Array] The headers that must be present in the request to result in the request being blocked
          #   parameters [Array] The parameters that must be present in the request
          #                       to result in the request being blocked.
          #   urls       [Array] The urls that must be present in the request to result in the request being blocked.
          #   uuids      [String] The UUID of the Virtual Patch }
          def virtual_patches
            @_virtual_patches ||= []
          end

          # Set the virtual patches array
          #
          # @param virtual_patches [Array<VirtualPatch>] Array of VirtualPatch: {
          #   name       [String] The name of the Virtual Patch
          #   headers    [Array] The headers that must be present in the request to result in the request being blocked
          #   parameters [Array] The parameters that must be present in the request
          #                       to result in the request being blocked.
          #   urls       [Array] The urls that must be present in the request to result in the request being blocked.
          #   uuids      [String] The UUID of the Virtual Patch }
          # @return virtual_patches [Array<VirtualPatch>] Array of VirtualPatch: {
          #   name       [String] The name of the Virtual Patch
          #   headers    [Array] The headers that must be present in the request to result in the request being blocked
          #   parameters [Array] The parameters that must be present in the request
          #                       to result in the request being blocked.
          #   urls       [Array] The urls that must be present in the request to result in the request being blocked.
          #   uuids      [String] The UUID of the Virtual Patch }
          def virtual_patches= virtual_patches
            @_virtual_patches = virtual_patches if virtual_patches.is_a? Array
          end

          # Converts settings into Agent Settings understandable hash {RULE_ID => MODE}
          #
          # @return rules [Hash<RULE_ID => MODE>, nil] Hash with rule_id as key and mode as value
          def protection_rules_to_settings_hash
            return if protection_rules.empty?

            modes_by_id = {}
            protection_rules.each do |rule|
              PROTECT_RULES_MODE.include? rule[:mode]
              modes_by_id[rule[:id]] = rule[:mode]
            end
            modes_by_id
          end
        end
      end
    end
  end
end