namespace :dockerized do

desc 'build docker-compose services'
task :build do
  on roles(:app) do
    within release_path do
      docker_execute :build
    end
  end
end

desc 'shutdown all project services with docker-compose'
task :down do
  on roles(:app) do
    within release_path do
      docker_execute :down
    end
  end
end

desc 'boot up all docker-compose services'
task :up do
  on roles(:app) do
    within release_path do
      docker_execute :up, '-d'
    end
  end
end

desc 'restart services of docker-compose and if not services listed restart all services'
task :restart do
  on roles(:app) do
    within release_path do
      services = Array(fetch(:dockerized_restart))
      if services.empty?
        docker_execute :down
        docker_execute :up
      else
        docker_execute :stop, *services
        docker_execute :up, '-d', *services
      end
    end
  end
end

desc 'delete docker images that are not related to current build'
task :clean do
  on roles(:app) do
    within release_path do
      images_to_delete = capture('docker images -f "dangling=true" -q')
      execute 'docker rmi -f $(docker images -f "dangling=true" -q)' unless images_to_delete.empty?
    end
  end
end

desc 'execute a set of rake tasts inside the web container'
task :rake_tasks do
  on roles(:app) do
    within release_path do
      docker_rake(*fetch(:dockerized_rake_tasks)) if fetch(:dockerized_rake_tasks)
    end
  end
end

desc 'run an interactive command inside the web container'
task :run do
  on roles(:app) do |host|
    command = ARGV[2..-1].join(' ')
    docker_execute_interactively host, command
  end
end

namespace :load do
  task :defaults do
    set :dockerized_restart, fetch(:dockerized_restart, nil)
    set :dockerized_web_service, fetch(:dockerized_web_service, :web)
    set :dockerized_rake_tasks, fetch(:dockerized_rake_tasks, nil)
  end
end

def docker_rake(*args)
  docker_execute('run', '--rm', fetch(:dockerized_web_service), 'rake', *args)
end

def docker_execute(*args)
  execute('docker-compose', "-p #{fetch :application}", *args)
end

def docker_execute_interactively(host, command)
  user = host.user
  port = fetch(:port) || 22
  docker_run = "docker-compose -p #{fetch :application} run --rm #{fetch(:dockerized_web_service)} #{command}"
  exec "ssh -l #{user} #{host} -p #{port} -t 'cd #{deploy_to}/current && #{docker_run}'"
end

after 'deploy:updated',   'dockerized:build'
after 'deploy:published', 'dockerized:rake_tasks'
after 'deploy:published', 'dockerized:restart'
after 'deploy:cleanup',   'dockerized:clean'

end