module ZuoraConnect

def custom_logger(name: "", level: Rails.logger.present? ? Rails.logger.level : MonoLogger::INFO, type: :ougai)

def custom_logger(name: "", level: Rails.logger.present? ? Rails.logger.level : MonoLogger::INFO, type: :ougai)
  #puts name + ' - ' + {Logger::WARN => 'Logger::WARN', Logger::ERROR => 'Logger::ERROR', Logger::DEBUG => 'Logger::DEBUG', Logger::INFO => 'Logger::INFO' }[level] + ' - '
  if type == :ougai
    require 'ougai'
    require "ougai/formatters/customizable"
    #logger = Ougai::Logger.new(MonoLogger.new(STDOUT))
    logger = Ougai::Logger.new(STDOUT)
    logger.level = level
    if ZuoraConnect.configuration.json_logging
      logger.formatter = Ougai::Formatters::ConnectFormatter.new(name)
      logger.before_log = lambda do |data|
        data[:trace_id] = ZuoraConnect::RequestIdMiddleware.request_id if ZuoraConnect::RequestIdMiddleware.request_id.present?
        data[:zuora_trace_id] = ZuoraConnect::RequestIdMiddleware.zuora_request_id if ZuoraConnect::RequestIdMiddleware.zuora_request_id.present?
        #data[:traces] = {amazon_id: data[:trace_id], zuora_id: data[:zuora_trace_id]}
        if !['ElasticAPM', 'ResqueScheduler', 'ResquePool', 'Resque', 'Makara'].include?(name)
          if Thread.current[:appinstance].present? && Thread.current[:appinstance].id.present?
            data[:app_instance_id] = Thread.current[:appinstance].id
            logitems = Thread.current[:appinstance].logitems
            if logitems.present? && logitems.class == Hash
              data[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
              data[:organization] = logitems[:organization] if logitems[:organization].present?
            end
          end
        end
      end
    else
      logger.formatter = Ougai::Formatters::Customizable.new(
        format_err: proc do |data|
          next nil unless data.key?(:err)
          err = data.delete(:err)
          "  #{err[:name]} (#{err[:message]})\n #{err[:stack]}"
        end,
        format_data: proc do |data|
          format('%s %s: %s', 'DATA'.ljust(6), Time.now.strftime('%FT%T.%6NZ'), "#{data.to_json}") if data.present?
        end,
        format_msg: proc do |severity, datetime, _progname, data|
          msg = data.delete(:msg)
          format('%s %s: %s', severity.ljust(6), datetime, msg)
        end
      )
      logger.formatter.datetime_format = '%FT%T.%6NZ'
    end
  else
    logger = MonoLogger.new(STDOUT)
    logger.level = level
    logger.formatter =  proc do |serverity, datetime, progname, msg|
      begin
        msg = JSON.parse(msg)
      rescue JSON::ParserError => ex
      end
      if ZuoraConnect.configuration.json_logging
        require 'json'
        store = {
          name: name,
          level: serverity,
          timestamp: datetime.strftime('%FT%T.%6NZ'),
          pid: Process.pid,
          message: name == "ActionMailer" ? msg.strip : msg
        }
        if !['ElasticAPM', 'ResqueScheduler', 'ResquePool','Resque', 'Makara'].include?(name)
          if Thread.current[:appinstance].present? && Thread.current[:appinstance].id.present?
            store[:app_instance_id] = Thread.current[:appinstance].id
            logitems = Thread.current[:appinstance].logitems
            if logitems.present? && logitems.class == Hash
              store[:tenant_ids] = logitems[:tenant_ids] if logitems[:tenant_ids].present?
              store[:organization] = logitems[:organization] if logitems[:organization].present?
            end
          end
        end
        JSON.dump(store) + "\n"
      else
        format('%s %s: %s', serverity.ljust(6), datetime, msg) + "\n"
      end
    end
  end
  return logger
end