# 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
      # helper methods used for masking
      module MaskerUtils
        include Contrast::Utils::ObjectShare
        # Helper to deal with Protobuf FieldHash.
        #
        # @param field_hash [Protobuf::Field::FieldHash] hash to be masked
        # @param results [Array<Contrast::Api::Dtm::AttackResults>]
        # results to match against.
        # @return [Hash]
        def mask_field_hash field_hash, results
          return {} unless field_hash&.any?

          hash = {}
          # Because this is the start of a built string, we have to be sure that it is not frozen.
          masked = +''
          field_hash.each do |entry|
            # Protobuf::Field::FieldHash produces array, with the key as first param and value as second.
            new_value = entry[1].delete(SEMICOLON).split(SPACE)
            new_value.each do |value|
              arr = value.split(EQUALS)
              # Add to new hash.
              hash[arr[0]] = arr[1]
            end
            # Mask the newly created hash.
            mask_with_dictionary results, hash

            # Restore to original form.
            hash.each { |k, v| masked += "#{ k }=#{ v }; " }
            masked.rstrip!
            field_hash[entry[0]] = masked
          end
        end

        # Mask raw query as it comes from the env.
        # exp:
        # 'ssn=1234567&id=%272%20or%202%20=%202%27' =>
        # 'ssn=contrast-redacted-ssn&id=contrast-redacted-id'
        #
        # @param query [String]
        # @param results [Array<Contrast::Api::Dtm::AttackResults>]
        # results to match against.
        def mask_raw_query query, results
          masked = EMPTY_STRING
          hash = URI.decode_www_form(query).to_h
          mask_with_dictionary results, hash
          # Restore to string form.
          hash.each { |k, v| masked += "#{ k }=#{ v }&" }
          query = masked
          query.chomp!(masked[-1])
        end
      end
    end
  end
end