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

module Contrast
  module Components
    module Logger
      module InstanceMethods #:nodoc:
        def logger
          Contrast::Components::Logger::COMPONENT_INTERFACE
        end
      end
      ClassMethods = InstanceMethods

      # A wrapper build around the Common Agent Configuration project to allow
      # for access of the values contained in its
      # parent_configuration_spec.yaml.
      # Specifically, this allows for querying the state of the Agent Logger.
      class Interface
        include Contrast::Components::ComponentBase

        %w[error? warn? info? debug?].each do |level|
          define_method(level) { state.logger.send(level) }
        end

        # def trace? # TODO: RUBY-547
        #  config&.agent&.logger&.level && config.agent.logger.level.to_s.casecmp('TRACE').to_i.zero?
        # end

        def error *args
          log_with_level(*args, :error)
        end

        def warn *args
          log_with_level(*args, :warn)
        end

        def info *args
          log_with_level(*args, :info)
        end

        def debug *args
          log_with_level(*args, :debug)
        end

        def with_level *args
          log_with_level(*args)
        end

        def debug_with_time msg
          ret = nil
          a = Contrast::Utils::Timer.now_ms
          ret = yield if block_given?
          z = Contrast::Utils::Timer.now_ms
          log_with_level(nil, "#{ msg }: pid=#{ Process.pid }, elapsed=#{ z - a }ms", :debug)
          ret
        end

        # def trace_with_time msg # TODO: RUBY-547
        #  ret = nil
        #  unless trace?
        #    ret = yield if block_given?
        #    return ret
        #  end
        #
        #  a = Contrast::Utils::Timer.now_ms
        #  ret = yield if block_given?
        #  z = Contrast::Utils::Timer.now_ms
        #  log_with_level(nil, "#{ msg }: pid=#{ Process.pid }, elapsed=#{ z - a }ms", :debug)
        #  ret
        # end

        private

        def log_with_level *args
          if args.length == 2
            msg, level = *args
            state.cs__class.log_with_level(nil, msg, level)
          elsif args.length == 3
            exception, msg, level = *args
            state.cs__class.log_with_level(exception, msg, level)
          end

          nil
        rescue StandardError
          nil
        end
      end

      COMPONENT_INTERFACE = Interface.new
    end
  end
end