require ‘capistrano/unicorn/utility’

include CapistranoUnicorn::Utility

# Load default values the capistrano 3.x way. # See github.com/capistrano/capistrano/pull/605 namespace :load do

task :defaults do

  # Environments
  set :unicorn_env     , Proc.new{ fetch(:rails_env, 'production') }
  # Following recommendations from http://unicorn.bogomips.org/unicorn_1.html
  set :unicorn_rack_env, Proc.new{ fetch(:rails_env) == 'development' ? 'development' : 'deployment' }

  # Execution
  set :unicorn_user              , nil
  set :unicorn_bundle            , Proc.new{ fetch(:bundle_cmd, "bundle") }
  set :unicorn_bin               , "unicorn"
  set :unicorn_options           , ''
  set :unicorn_restart_sleep_time, 2

  # Relative paths
  set :app_subdir                        , ''
  set :unicorn_config_rel_path           , "config"
  set :unicorn_config_filename           , "unicorn.rb"
  set :unicorn_config_rel_file_path      , Proc.new{ File.join(fetch(:unicorn_config_rel_path), fetch(:unicorn_config_filename)) }
  set :unicorn_config_stage_rel_file_path, Proc.new{ File.join(fetch(:unicorn_config_rel_path), 'unicorn', "#{fetch(:unicorn_env)}.rb") }

  # Absolute paths
  # If you find the following confusing, try running 'cap unicorn:show_vars' -
  # it might help :-)
  set :app_path                      , Proc.new{ File.join(current_path, fetch(:app_subdir)) }
  set :unicorn_config_path           , Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_rel_path)) }
  set :unicorn_config_file_path      , Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_rel_file_path)) }
  set :unicorn_config_stage_file_path, Proc.new{ File.join(fetch(:app_path), fetch(:unicorn_config_stage_rel_file_path)) }
  set :unicorn_default_pid           , Proc.new{ File.join(fetch(:app_path), 'tmp', 'pids', 'unicorn.pid') }
  set :unicorn_pid, Proc.new{
    extracted_pid = extract_pid_file
    if extracted_pid
      extracted_pid
    else
      # TODO logger is not defined
      #logger.important "err :: failed to auto-detect pid from #{local_unicorn_config}"
      #logger.important "err :: falling back to default: #{unicorn_default_pid}"
      fetch :unicorn_default_pid
    end
  }
end

end

namespace :unicorn do

desc 'Debug Unicorn variables'
task :show_vars do
  on roles :app do
    puts <<-EOF.gsub(/^ +/, '')
      # Environments
      rails_env          #{fetch :rails_env}
      unicorn_env        #{fetch :unicorn_env}
      unicorn_rack_env   #{fetch :unicorn_rack_env}

      # Execution
      unicorn_user       #{fetch(:unicorn_user).inspect}
      unicorn_bundle     #{fetch :unicorn_bundle}
      unicorn_bin        #{fetch :unicorn_bin}
      unicorn_options    #{fetch :unicorn_options}
      unicorn_restart_sleep_time  #{fetch :unicorn_restart_sleep_time}

      # Relative paths
      app_subdir                         #{fetch :app_subdir}
      unicorn_config_rel_path            #{fetch :unicorn_config_rel_path}
      unicorn_config_filename            #{fetch :unicorn_config_filename}
      unicorn_config_rel_file_path       #{fetch :unicorn_config_rel_file_path}
      unicorn_config_stage_rel_file_path #{fetch :unicorn_config_stage_rel_file_path}

      # Absolute paths
      app_path                  #{fetch :app_path}
      unicorn_pid               #{fetch :unicorn_pid}
      unicorn_config_path       #{fetch :unicorn_config_path}
      unicorn_config_file_path  #{fetch :unicorn_config_file_path}
      unicorn_config_stage_file_path
      ->                        "#{fetch :unicorn_config_stage_file_path}
    EOF
  end
end

desc 'Start Unicorn master process'
task :start do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    execute start_unicorn
  end
end

desc 'Stop Unicorn'
task :stop do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    execute kill_unicorn('QUIT')
  end
end

desc 'Immediately shutdown Unicorn'
task :shutdown do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    execute kill_unicorn('TERM')
  end
end

desc 'Restart Unicorn'
task :restart do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    duplicate_unicorn
    execute :sleep, fetch(:unicorn_restart_sleep_time)

    if old_unicorn_is_running?
      unicorn_send_signal('QUIT', get_old_unicorn_pid)
    end
  end
end

desc 'Duplicate Unicorn'
task :duplicate do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    duplicate_unicorn
  end
end

desc 'Reload Unicorn'
task :reload do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    if unicorn_is_running?
      unicorn_send_signal('HUP')
    else
      start_unicorn
    end
  end
end

desc 'Add a new worker'
task :add_worker do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    if unicorn_is_running?
      unicorn_send_signal('TTIN')
    end
  end
end

desc 'Remove amount of workers'
task :remove_worker do
  on roles unicorn_roles, reject: lambda { |h| h.properties.no_release } do
    if unicorn_is_running?
      unicorn_send_signal('TTOU')
    end
  end
end

end