module Softwear
  module Library
    def self.capistrano(context)
      context.instance_eval do
        Rake::Task["deploy:compile_assets"].clear

        ruby = fetch(:rvm_ruby_string) || fetch(:rvm_ruby_version)

        namespace :deploy do

          desc 'Assure softwear-lib is up to date before deploying'
          task :update_softwear_lib do
            on roles(:app), in: :sequence do
              execute "~/.rvm/bin/rvm #{ruby} do gem install --no-ri --no-rdoc softwear-lib"
            end
          end

          desc 'Signal the running rails app to restart'
          task :restart do
            on roles([:web, :app]), in: :sequence, wait: 5 do
              execute :mkdir, '-p', "#{release_path}/tmp"
              execute :touch, release_path.join('tmp/restart.txt')
            end
          end

          after :publishing, :restart_sidekiq_manager do
            on roles(:sidekiq) do
              execute 'sudo restart sidekiq-manager'
            end
          end

          # This is more problematic than helpful
=begin
          if !$LOAD_PATH.grep(/sunspot_solr/).empty? || fetch(:no_reindex)
            before :publishing, :reindex_solr do
              on roles(:db) do
                with rails_env: fetch(:rails_env) || fetch(:stage) do
                  within(release_path) do
                    execute :rake, 'sunspot:solr:reindex'
                  end
                end
              end
            end
          end
=end

          # This is no longer necessary
          # before :updating, :update_softwear_lib
          after :publishing, :restart

          desc 'Compile assets'
          task :compile_assets => [:set_rails_env] do
            invoke 'deploy:assets:precompile_local'
            invoke 'deploy:assets:backup_manifest'
          end

          namespace :assets do

            desc "Precompile assets locally and then rsync to web servers"
            task :precompile_local do
              # compile assets locally
              run_locally do
                execute "RAILS_ENV=#{fetch(:stage)} bundle exec rake assets:precompile"
              end

              # rsync to each server
              assets_dir = "public/#{fetch(:assets_prefix) || 'assets'}"
              local_dir  = "./#{assets_dir}/"
              on roles( fetch(:assets_roles, [:web]) ) do
                # this needs to be done outside run_locally in order for host to exist
                remote_dir = "#{host.user}@#{host.hostname}:#{release_path}/#{assets_dir}"

                execute "mkdir -p #{release_path}/#{assets_dir}"
                run_locally { execute "rsync -av --delete #{local_dir} #{remote_dir}" }

                if fetch(:asset_sync)
                  with rails_env: fetch(:rails_env) || fetch(:stage) do
                    within(release_path) do
                      if respond_to?(:with_rvm)
                        with_rvm(fetch(:task_ruby_version)) { execute :rake, 'assets:sync' }
                      else
                        execute :rake, 'assets:sync'
                      end
                    end
                  end
                end
              end

              # clean up
              run_locally { execute "rm -rf #{local_dir}" }
            end
          end

        end
      end
    end
  end
end