# frozen_string_literal: true

module Litany
  class LogFormatter
    class << self
      attr_accessor :log_format
    end

    self.log_format = "[%s] %s (%s) -> %s\n"

    class << self
      def call(severity, time, program_name, message)
        log_format % [
          format_time(time),
          color_severity(severity.rjust(8)),
          program_name,
          message_output(message)
        ]
      end

      private

      def format_time(time)
        time.utc.strftime('%Y-%m-%d %H:%M:%S')
      end

      def color_severity(severity)
        case severity
          when /DEBUG/
            Rainbow(severity).cyan.italic
          when /INFO/
            Rainbow(severity).cyan
          when /WARN/
            Rainbow(severity).yellow
          when /ERROR/, /FATAL/, /UNKNOWN/
            Rainbow(severity).red
          else
            severity
        end
      end

      def message_output(message)
        case message
          when ::String
            message
          when ::Exception
            parts = ['']
            parts << Rainbow('Message: ').magenta
            parts << "#{message.message} (#{message.class})".indent(1, 4)
            unless message.backtrace.nil?
              parts << Rainbow('Backtrace:').magenta
              parts += message.backtrace.collect { |line| line.indent(1, 4) }
            end
            parts.join("\n")
          else
            message.inspect
        end
      end
    end
  end
end
