lib/sentry_logging.rb
# frozen_string_literal: true

require 'sentry_logging'

module SentryLogging
  # WARNING: This module is deprecated, and will be removed in October 2025. Please use Vets::SharedLogging instead.
  #
  # Migration Documentation: https://depo-platform-documentation.scrollhelp.site/developer-docs/how-to-migrate-from-sentrylogging-to-vets-sharedlo
  #
  # If your team currently uses this module, please see the migration guide above for step-by-step instructions
  # on transitioning to Vets::SharedLogging.
  unless Rails.env.test?
    ActiveSupport::Deprecation
      .new.warn('SentryLogging is deprecated and will be removed in October 2025. Use Vets::SharedLogging instead.')
  end
  extend self

  def log_message_to_sentry(message, level, extra_context = {}, tags_context = {})
    level = normalize_level(level, nil)
    formatted_message = extra_context.empty? ? message : "#{message} : #{extra_context}"
    rails_logger(level, formatted_message)

    if Settings.sentry.dsn.present?
      set_sentry_metadata(extra_context, tags_context)
      Sentry.capture_message(message, level:)
    end
  end

  def log_exception_to_sentry(exception, extra_context = {}, tags_context = {}, level = 'error')
    level = normalize_level(level, exception)

    if Settings.sentry.dsn.present?
      set_sentry_metadata(extra_context, tags_context)
      Sentry.capture_exception(exception.cause.presence || exception, level:)
    end

    if exception.is_a? Common::Exceptions::BackendServiceException
      rails_logger(level, exception.message, exception.errors, exception.backtrace)
    else
      rails_logger(level, "#{exception.message}.")
    end
    rails_logger(level, exception.backtrace.join("\n")) unless exception.backtrace.nil?
  end

  def normalize_level(level, exception)
    # https://docs.sentry.io/platforms/ruby/usage/set-level/
    # valid sentry levels: log, debug, info, warning, error, fatal
    level = case exception
            when Pundit::NotAuthorizedError
              'info'
            when Common::Exceptions::BaseError
              exception.sentry_type.to_s
            else
              level.to_s
            end

    return 'warning' if level == 'warn'

    level
  end

  def rails_logger(level, message, errors = nil, backtrace = nil)
    # rails logger uses 'warn' instead of 'warning'
    level = 'warn' if level == 'warning'
    if errors.present?
      error_details = errors.first.attributes.compact.reject { |_k, v| v.try(:empty?) }
      Rails.logger.send(level, message, error_details.merge(backtrace:))
    else
      Rails.logger.send(level, message)
    end
  end

  def non_nil_hash?(h)
    h.is_a?(Hash) && !h.empty?
  end

  private

  def set_sentry_metadata(extra_context, tags_context)
    Sentry.set_extras(extra_context) if non_nil_hash?(extra_context)
    Sentry.set_tags(tags_context) if non_nil_hash?(tags_context)
  end
end
