require "socket"

module Lumber

  # Initializes log4r system.  Needs to happen in
  # config/environment.rb before Rails::Initializer.run
  #
  # Options:
  #
  # * :root - defaults to RAILS_ROOT if defined
  # * :env - defaults to RAILS_ENV if defined
  # * :config_file - defaults to <root>}/config/log4r.yml
  # * :log_file - defaults to <root>}/log/<env>.log
  #
  # All config options get passed through to the log4r
  # configurator for use in defining outputters
  #
  def self.init(opts = {})
    opts[:root] ||= RAILS_ROOT if defined?(RAILS_ROOT)
    opts[:env] ||= RAILS_ENV if defined?(RAILS_ENV)
    opts[:config_file] ||= "#{opts[:root]}/config/log4r.yml"
    opts[:log_file] ||= "#{opts[:root]}/log/#{opts[:env]}.log"
    raise "Lumber.init missing one of :root, :env" unless opts[:root] && opts[:env]

    cfg = Log4r::YamlConfigurator
    opts.each do |k, v|
      cfg[k.to_s] = v
    end
    cfg['hostname'] = Socket.gethostname

    cfg.load_yaml_file(opts[:config_file])

    # Workaround for rails bug: http://dev.rubyonrails.org/ticket/8665
    if defined?(RAILS_DEFAULT_LOGGER)
      Object.send(:remove_const, :RAILS_DEFAULT_LOGGER)
    end
    Object.const_set('RAILS_DEFAULT_LOGGER', Log4r::Logger['rails'])

  end

  # Makes :logger exist independently for subclasses and sets that logger
  # to one that inherits from base_class for each subclass as its created.
  # This allows you to have a finer level of control over logging, for example,
  # put just a single class, or heirarchy of classes, into debug log level
  #
  # for example:
  #
  #   Lumber.setup_logger_heirarchy(ActiveRecord::Base, "rails::models")
  #
  # causes all models that get created to have a log4r logger named
  # "rails::models::<class_name>".  This class can individually be
  # put into debug log mode in production (see {log4r docs}[http://log4r.sourceforge.net/manual.html]), and log
  # output will include "<class_name>" on every log from this class
  # so that you can tell where a log statement came from
  #
  def self.setup_logger_heirarchy(base_class, parent_fullname)
    base_class.class_eval do
      class_inheritable_accessor :logger
      self.logger = Log4r::Logger.new(parent_fullname)

      class << self
        def inherited_with_lumber_log4r(subclass)
          inherited_without_lumber_log4r(subclass)
          subclass.logger = Log4r::Logger.new("#{logger.fullname}::#{subclass.name}")
        end
        alias_method_chain :inherited, :lumber_log4r
      end

    end
  end

end