def db_tasks

Rake::Task.tasks.select do |t|
  t.name.start_with?('db:')
end

end

def wrappable_task?(task)

fail ArgumentError unless task.name.start_with?('db:')

case task.name
  when /^db:test\b/, /^db:structure\b/, /^db:schema\b/, /^db:setup\b/, /^db:purge\b/,
       /^db:reset\b/, /^db:load_config\b/, /^db:create\b/, /^db:drop\b/
    false
  else
    true
end

end

def using_each_tenant(&block)

tenants = if ENV['T']
  ENV['T'].split(/\s*,\s*/).map do |tenant_id|
    ::Cell::Model.cell_find(tenant_id).tap do |r|
      fail "Unable to load tenant: #{tenant_id}" if r.nil?
    end
  end
else
  ::Cell::Model.respond_to?(:find_each) ? ::Cell::Model.find_each : ::Cell::Model.each
end

tenants.each do |t|
  Cell::Model.use(t, &block)
end

end

namespace :cell do

task :eager => 'environment' do
  Rails.application.eager_load!
end

end

db_tasks.each do |db_task|

if wrappable_task?(db_task)
  # We need to have the model the user has chosen to be Cell::Model to have
  # been loaded.  The easy way is to punt and eager_load all rake tasks, but
  # we'll try to selectively do it for certain tasks by adding the
  # dependency.
  task db_task => 'cell:eager'

  if db_task.comment
    desc "run `#{db_task.name}' for all tenants, or each in $T=t1,t2,..."
  end
  task "cell:#{db_task.name}" => 'cell:eager' do |t|
    Rails.application.eager_load!
    using_each_tenant do |tenant|
      puts "Running #{db_task.name} for tenant '#{tenant.cell_id}'"
      Rake::Task[db_task.name].execute
    end
  end
end

end