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

require 'contrast/agent/disable_reaction'
require 'contrast/components/logger'

module Contrast
  module Agent
    # Because communication between the Agent/Service and TeamServer can only be initiated by outbound connections
    # from the Agent/Service, we must provide a mechanism for the TeamServer to direct the Agent to take a specific
    # action. This action is referred to as a Reaction. This class is how we handle those Reaction messages.
    module ReactionProcessor
      extend Contrast::Components::Logger::InstanceMethods

      # Process the given Reactions from the application settings based on what
      # TeamServer has indicated. Each Reaction will result in a log message
      # and, optionally, an action.
      #
      # @param application_settings [Contrast::Api::Settings::ApplicationSettings]
      #   those settings which the Service has relayed from TeamServer.
      def self.process application_settings
        return unless application_settings&.reactions&.any?

        application_settings.reactions.each do |reaction|
          # The enums are all uppercase, we need to downcase them before attempting to log.
          level = if reaction.log_level.nil?
                    :error
                  else
                    reaction.log_level.name.downcase # rubocop:disable Security/Module/Name -- ruby logger builtin.
                  end

          logger.with_level(level, reaction.message) if reaction.message

          case reaction.operation
          when Contrast::Api::Settings::Reaction::Operation::DISABLE
            Contrast::Agent::DisableReaction.run(reaction, level)
          when Contrast::Api::Settings::Reaction::Operation::NOOP
            # NOOP
          else
            logger.warn('ReactionProcessor received a reaction with an unknown operation',
                        operation: reaction.operation)
          end
        end
      end
    end
  end
end