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

require 'contrast/agent/reporting/reporting_events/finding_event'

module Contrast
  module Agent
    module Assess
      module Property
        # This module serves to hold the functionality required for the
        # management of our dataflow events.
        #
        # @attr_reader event [Contrast::Agent::Assess::ContrastEvent] the
        #   latest event to track
        module Evented
          attr_reader :event

          # Create a new event and add it to the event set.
          #
          # @param event_data [Contrast::Agent::Assess::Events::EventData]
          # @param source_type [String] the type of this source, from the
          #   source_node, or a KEY_TYPE if invoked for a map
          # @param source_name [String, nil] the name of this source, i.e.
          #   the key used to accessed if from a map or nil if a type like
          #   BODY
          def build_event event_data, source_type = nil, source_name = nil
            @event = Contrast::Agent::Reporting::FindingEvent.new(event_data, source_type, source_name)
            report_sources(event_data.tagged, @event)
          end

          private

          # Append the sources of the given event to the current request
          # context's observed route
          #
          # @param tagged [Object] The Target of the Event
          # @param event [Contrast::Agent::Reporting::FindingEvent]
          def report_sources tagged, event
            return unless tagged && !tagged.to_s.empty?
            return unless event.source_type
            return unless (current_request = Contrast::Agent::REQUEST_TRACKER.current)

            event.event_sources&.each do |event_source|
              if current_request.observed_route.sources.any? do |source|
                source.source_type == event_source.source_type && source.source_name == event_source.source_name
              end

                next
              end

              current_request.observed_route.sources << event_source
            end
          end
        end
      end
    end
  end
end