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

require 'contrast/api/dtm.pb'
require 'contrast/components/logger'
require 'contrast/utils/string_utils'
require 'contrast/utils/timer'

module Contrast
  module Api
    module Decorators
      # Used to decorate the {Contrast::Api::Dtm::Address} protobuf model so it
      # can own some of the data massaging required for Request dtm. Only works
      # as an extension of that class.
      module Address
        def self.included klass
          klass.extend(ClassMethods)
        end

        # Used to add class methods to the ApplicationUpdate class on inclusion of the decorator
        module ClassMethods
          include Contrast::Components::Logger::InstanceMethods
          # receiver is memoized because it is the address/host/port of the server, once we
          # resolve this for the first time, it shouldn't change
          #
          # @return [Contrast::Api::Dtm::Address] the address of this server
          def build_receiver
            @_build_receiver ||= begin
              address = new
              address.host = 'localhost'
              address.ip = '127.0.0.1' # rubocop:disable Style/IpAddresses
              begin
                Timeout.timeout(1) do
                  address.host = Contrast::Utils::StringUtils.force_utf8(Socket.gethostname)
                  address.ip = Contrast::Utils::StringUtils.force_utf8(Resolv.getaddress(address.host))
                end
              rescue StandardError => e
                logger.warn('Unable to resolve host or ip', e, address: address)
              end
              address
            end
          end

          # Parse out the sender of the Request and return it as an Address
          #
          # @return [Contrast::Api::Dtm::Address] the address from which the
          #   request originated
          def build_sender request
            sender = new
            sender.ip = Contrast::Utils::StringUtils.force_utf8(request.ip)
            sender
          end
        end
      end
    end
  end
end

Contrast::Api::Dtm::Address.include(Contrast::Api::Decorators::Address)