module Bullet

def add_whitelist(options)

def add_whitelist(options)
  @whitelist[options[:type]][options[:class_name].classify] ||= []
  @whitelist[options[:type]][options[:class_name].classify] << options[:association].to_sym
end

def bullet_logger=(active)

def bullet_logger=(active)
  if active
    require 'fileutils'
    root_path = "#{rails? ? Rails.root.to_s : Dir.pwd}"
    FileUtils.mkdir_p(root_path + '/log')
    bullet_log_file = File.open("#{root_path}/log/bullet.log", 'a+')
    bullet_log_file.sync = true
    UniformNotifier.customized_logger = bullet_log_file
  end
end

def counter_cache_enable?

def counter_cache_enable?
  self.enable? && !!@counter_cache_enable
end

def debug(title, message)

def debug(title, message)
  puts "[Bullet][#{title}] #{message}" if ENV['DEBUG'] == 'true'
end

def enable=(enable)

def enable=(enable)
  @enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
  if enable?
    reset_whitelist
    unless orm_pathches_applied
      self.orm_pathches_applied = true
      Bullet::Mongoid.enable if mongoid?
      Bullet::ActiveRecord.enable if active_record?
    end
  end
end

def enable?

def enable?
  !!@enable
end

def end_request

def end_request
  Thread.current[:bullet_start] = nil
  Thread.current[:bullet_notification_collector] = nil
  Thread.current[:bullet_object_associations] = nil
  Thread.current[:bullet_possible_objects] = nil
  Thread.current[:bullet_impossible_objects] = nil
  Thread.current[:bullet_call_object_associations] = nil
  Thread.current[:bullet_eager_loadings] = nil
  Thread.current[:bullet_counter_possible_objects] = nil
  Thread.current[:bullet_counter_impossible_objects] = nil
end

def footer_info

def footer_info
  info = []
  for_each_active_notifier_with_notification do |notification|
    info << notification.short_notice
  end
  info
end

def for_each_active_notifier_with_notification

def for_each_active_notifier_with_notification
  UniformNotifier.active_notifiers.each do |notifier|
    notification_collector.collection.each do |notification|
      notification.notifier = notifier
      yield notification
    end
  end
end

def gather_inline_notifications

def gather_inline_notifications
  responses = []
  for_each_active_notifier_with_notification do |notification|
    responses << notification.notify_inline
  end
  responses.join( "\n" )
end

def get_whitelist_associations(type, class_name)

def get_whitelist_associations(type, class_name)
  Array(@whitelist[type][class_name])
end

def n_plus_one_query_enable?

def n_plus_one_query_enable?
  self.enable? && !!@n_plus_one_query_enable
end

def notification?

def notification?
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
  notification_collector.notifications_present?
end

def notification_collector

def notification_collector
  Thread.current[:bullet_notification_collector]
end

def perform_out_of_channel_notifications(env = {})

def perform_out_of_channel_notifications(env = {})
  for_each_active_notifier_with_notification do |notification|
    notification.url = [env['HTTP_HOST'], env['REQUEST_URI']].compact.join
    notification.notify_out_of_channel
  end
end

def profile

def profile
  Bullet.start_request if Bullet.enable?
  yield
  if Bullet.enable? && Bullet.notification?
    Bullet.perform_out_of_channel_notifications
  end
  Bullet.end_request if Bullet.enable?
end

def raise=(should_raise)

def raise=(should_raise)
  UniformNotifier.raise=(should_raise ? Notification::UnoptimizedQueryError : false)
end

def reset_whitelist

def reset_whitelist
  @whitelist = {:n_plus_one_query => {}, :unused_eager_loading => {}, :counter_cache => {}}
end

def stacktrace_includes

def stacktrace_includes
  @stacktrace_includes || []
end

def start?

def start?
  Thread.current[:bullet_start]
end

def start_request

def start_request
  Thread.current[:bullet_start] = true
  Thread.current[:bullet_notification_collector] = Bullet::NotificationCollector.new
  Thread.current[:bullet_object_associations] = Bullet::Registry::Base.new
  Thread.current[:bullet_call_object_associations] = Bullet::Registry::Base.new
  Thread.current[:bullet_possible_objects] = Bullet::Registry::Object.new
  Thread.current[:bullet_impossible_objects] = Bullet::Registry::Object.new
  Thread.current[:bullet_eager_loadings] = Bullet::Registry::Association.new
  Thread.current[:bullet_counter_possible_objects] ||= Bullet::Registry::Object.new
  Thread.current[:bullet_counter_impossible_objects] ||= Bullet::Registry::Object.new
end

def unused_eager_loading_enable?

def unused_eager_loading_enable?
  self.enable? && !!@unused_eager_loading_enable
end

def warnings

def warnings
  notification_collector.collection.inject({}) do |warnings, notification|
    warning_type = notification.class.to_s.split(':').last.tableize
    warnings[warning_type] ||= []
    warnings[warning_type] << notification
    warnings
  end
end