def exit_if_production

if Rails.env.production?
  puts 'This task cannot be run in production environment'.red
  exit!
end

end

module Rake

class Task
  def self.reinvoke(*params, &block)
    invoke *params, &block
    reenable
  end
end

end

namespace :database do

desc "Create database if it does not exist"
task :create, :id do |name, params|
  puts 'Creating: ' + params[:id].to_s.green
  Inf.databases.connect :system
  Inf.databases.create params[:id] if ! Inf.databases.available? params[:id]
end

desc "Drop database if exists"
task :drop, :id do |name, params|
  puts 'Dropping: ' + params[:id].to_s.green
  Inf.databases.connect :system
  Inf.databases.drop params[:id] if Inf.databases.available? params[:id]
end

desc "Migrate database"
task :migrate, :id, :version do |name, params|
  puts 'Migrating: ' + params[:id].to_s.green
  Inf.databases.connect params[:id]
  ActiveRecord::Base.logger.level = Logger::INFO if ActiveRecord::Base.logger
  current_version = ActiveRecord::Migrator.current_version
  target_version = (params[:version] || ActiveRecord::Migrator.last_version).to_i
  ActiveRecord::Migrator.migrate ActiveRecord::Migrator.migrations_paths, target_version
  ActiveRecord::Migrator.migrations(ActiveRecord::Migrator.migrations_paths).each do |migration|
    if target_version < current_version
      puts "Rollbacked: - #{migration.version} - #{migration.name.green} - #{migration.filename}" if migration.version >= target_version && migration.version < current_version
    else
      puts "Migrated: - #{migration.version} - #{migration.name.green} - #{migration.filename}" if migration.version > current_version && migration.version <= target_version
    end
  end
end

desc "Rollback database"
task :rollback, :id, :version do |name, params|
  puts 'Rollbacking: ' + params[:id].to_s.green
  Inf.databases.connect params[:id]
  ActiveRecord::Base.logger.level = Logger::INFO if ActiveRecord::Base.logger
  current_version = ActiveRecord::Migrator.current_version
  all_versions = ActiveRecord::Migrator.get_all_versions
  previous_index = all_versions.index(current_version) - 1
  previous_index = 0 if previous_index < 0
  previous_version = all_versions[previous_index]
  target_version = (params[:version] || previous_version).to_i
  ActiveRecord::Migrator.migrate ActiveRecord::Migrator.migrations_paths, target_version
  ActiveRecord::Migrator.migrations(ActiveRecord::Migrator.migrations_paths).each do |migration|
    if target_version < current_version
      puts "Rollbacked: - #{migration.version} - #{migration.name.green} - #{migration.filename}" if migration.version >= target_version && migration.version < current_version
    else
      puts "Migrated: - #{migration.version} - #{migration.name.green} - #{migration.filename}" if migration.version > current_version && migration.version <= target_version
    end
  end
end

desc "Seed database"
task :seed, :id do |name, params|
  puts 'Seeding: ' + params[:id].to_s.green
  Inf.databases.connect params[:id]
  load Inf.path.rails.db_dir + '/seeds.rb'
end

desc "Drop, create, then migrate database"
task :reset, :id do |name, params|
  Rake::Task['database:drop'].reinvoke params[:id]
  Rake::Task['database:create'].reinvoke params[:id]
  Rake::Task['database:migrate'].reinvoke params[:id]
end

namespace :reset do
  desc "Reset then seed database"
  task :seed, :id do |name, params|
    Rake::Task['database:reset'].reinvoke params[:id]
    Rake::Task['database:seed'].reinvoke params[:id]
  end
end

end

namespace :databases do

desc "Create all databases that dont exist"
task :create do
  Inf.databases.configs.each { |id, config| Rake::Task['database:create'].reinvoke id }
end

desc "Drop all databases that exist"
task :drop do |name, params|
  exit_if_production
  Inf.databases.configs.each { |id, config| Rake::Task['database:drop'].reinvoke id }
end

desc "Migrate all databases"
task :migrate, :version do |name, params|
  Inf.databases.configs.each { |id, config| Rake::Task['database:migrate'].reinvoke id, params[:version] }
end

desc "Rollback all databases"
task :rollback, :version do |name, params|
  Inf.databases.configs.each { |id, config| Rake::Task['database:rollback'].reinvoke id }
end

desc "Drop, create, migrate all databases"
task :reset do |name, params|
  exit_if_production
  Inf.databases.configs.each { |id, config| Rake::Task['database:reset'].reinvoke id }
end

desc "Seed all databases"
task :seed do |name, params|
  exit_if_production params
  Inf.databases.configs.each { |id, config| Rake::Task['database:seed'].reinvoke id }
end

namespace :reset do
  desc "Reset then seed all databases"
  task :seed do |name, params|
    exit_if_production params
    Inf.databases.configs.each { |id, config| Rake::Task['database:reset:seed'].reinvoke id }
  end
end

end