require “active_record”

namespace :compass_ae do

namespace :backup do

      PG_BACKUP_DIR = '/backup/postgres'
      SU_POSTGRES = true # set this to false on OS X and true on debian
      TIMESTAMP_FORMAT = "%Y-%m-%d_%Hh%Mm%Ss" # keep a single underscore or the purge_old task will break
      @purge_dumps_older_than = 2.weeks.ago

      desc 'backup all postgres databases'
  task :postgres => :environment do
    db_config = Rails.configuration.database_configuration[Rails.env]
    host = db_config['host'].blank? ? 'localhost' : db_config['host']
    username = db_config['username'].blank? ? 'postgres' : db_config['username']
    pgpw = ENV['PGPASSWORD'].nil? ? '' : "PGPASSWORD=#{ENV['PGPASSWORD']}"

    create_directory(PG_BACKUP_DIR)

    databases = ActiveRecord::Base.connection.select_values('SELECT datname FROM pg_database;')

    puts red("Backing up ALL postgres databases via pg_dump")
    databases.each do |db|
      unless db == "template0"
        puts "Dumping #{db} to #{PG_BACKUP_DIR}"
        cmd = "#{pgpw} pg_dump -U #{username} -h #{host} #{db} > #{PG_BACKUP_DIR}/#{db}_#{Time.now.strftime(TIMESTAMP_FORMAT)}.pgsql"
        cmd = "sudo su postgres -c \"#{cmd}\"" if SU_POSTGRES
        execute_command(cmd)
      else
        puts "Skipping template0 database ..."
      end
    end

    puts "\nBackup Complete."
  end

  namespace :postgres do
    # age should be in days
    task :purge_old, [:age] => :environment do |t,args|
      db_config = Rails.configuration.database_configuration[Rails.env]
      host = db_config['host'].blank? ? 'localhost' : db_config['host']
      username = db_config['username'].blank? ? 'postgres' : db_config['username']
      pgpw = ENV['PGPASSWORD'].nil? ? '' : "PGPASSWORD=#{ENV['PGPASSWORD']}"

      age = (args.age.blank? ? @purge_dumps_older_than : args.age.to_i.days.ago)
      puts "Purging postgres dumps older than #{age}"
      puts green("Default is 2 weeks. You can pass in number of days if you want something different.") if args.age.blank?
      puts green("Example: rake compass_ae:backup:postgres:purge_old[7]") if args.age.blank?

      chdir(PG_BACKUP_DIR)

      # get list of files and loop thru them
      files = Dir.glob("*.pgsql")

      files.each do |f|
        puts "Examining dump #{f}"
        # split filename
        filename_split = f.split('_')

        # get timestamp
        timestamp = filename_split[-2] + ' ' + filename_split[-1]
        timestamp = timestamp.gsub('.pgsql', '')
        timestamp = timestamp.gsub('h', ':')
        timestamp = timestamp.gsub('m', ':')
        timestamp = timestamp.gsub('s', '')

        # convert timestamp to Time object
        timeobject = Time.parse(timestamp)

        # compare time object with purge_dumps_older_than and delete if too old
        if timeobject < age
          puts red("Purging dump #{f}: Older than #{age}")
          cmd = "rm -f #{f}"
          execute_command(cmd)
        end        
      end

    end
  end

  def create_directory(foldername)
    FileUtils.mkdir_p(foldername) unless File.directory?(foldername)
  end

  def green(text)
    colorize(text, "\033[32m")
  end

  def red(text)
    colorize(text, "\033[31m")
  end

  def colorize(text, color_code)
    "#{color_code}#{text}\033[0m"
  end

  def execute_command(cmd)
    puts green(cmd)
    system cmd
  end    
end

end