#!/usr/bin/env ruby

require 'optparse'

OptionParser.new do |opts|
  opts.banner = "Usage: #{File.basename($0)} [path]"

  opts.on("-h", "--help", "Displays this help info") do
    puts opts
    exit 0
  end

  begin
    opts.parse!(ARGV)
  rescue OptionParser::ParseError => e
    warn e.message
    puts opts
    exit 1
  end
end

if ARGV.empty?
  abort "Please specify the directory to depify, e.g. `#{File.basename($0)} .'"
elsif !File.exists?(ARGV.first)
  abort "`#{ARGV.first}' does not exist."
elsif !File.directory?(ARGV.first)
  abort "`#{ARGV.first}' is not a directory."
elsif ARGV.length > 1
  abort "Too many arguments; please specify only the directory to capify."
end

def unindent(string)
  indentation = string[/\A\s*/]
  string.strip.gsub(/^#{indentation}/, "")
end


caprc = unindent(<<-FILE)
  # .caprc - Capistrano configs (added by deprec gem [www.deprec.org])
  #
  # Include settings that you want active whenever you use Capistrano
  # You can over ride these for particular projects by putting entries
  # into Capfile or deploy.rb for those projects
  #
  # Uncomment any of the following entries to enable them.
  #
  # Include deprec - deployment recipes for Capistrano (www.deprec.org)
  #
  require 'deprec'
  #
  # SSH options
  #
  # Use ssh keys instead of typing password every time
  # Replace with the path to your ssh public key
  # ssh_options[:keys] = %w(/path/to/your_home_dir/.ssh/id_rsa)
  #
  # Allow ssh keys to be forwarded (to scm server, through :gateway, etc) 
  # ssh_options[:forward_agent] = true 
  #
  # Stop some annoying warnings
  # ssh_options[:paranoid] = false
FILE

files = {
  "Capfile" => unindent(<<-FILE),
    load 'deploy' if respond_to?(:namespace) # cap2 differentiator
    Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
    Dir['config/*/recipes.rb'].each { |plugin| load(plugin) }
    load 'config/deploy'
  FILE

  "config/deploy.rb" => unindent(<<-FILE),
    require 'deprec'
  
    set :application, "set your application name here"
    set :domain, "set domain name project will be served on here"
    set :repository,  "svn+ssh://\#{domain}/var/www/apps/\#{application}/repos/trunk"
    # set :gems_for_project, %w(dr_nic_magic_models swiftiply) # list of gems to be installed
    
    # Update these if you're not running everything on one host.
    role :app, domain
    role :web, domain
    role :db,  domain, :primary => true
    role :scm, domain # used by deprec if you want to install subversion

    # If you aren't deploying to /var/www/apps/\#{application} on the target
    # servers (which is the deprec default), you can specify the actual location
    # via the :deploy_to variable:
    # set :deploy_to, "/var/www/\#{application}"

    # If you aren't using Subversion to manage your source code, specify
    # your SCM below:
    # set :scm, :subversion
    
    namespace :deploy do
      task :restart, :roles => :app, :except => { :no_release => true } do
        top.deprec.mongrel.restart
      end
    end
    
  FILE
}

def create_file(file, content)
  if !File.exists?(File.dirname(file))
    puts "[add] creating directory `#{File.dirname(file)}'"
    Dir.mkdir(File.dirname(file))
  end
  if File.exists?(file)
    warn "[skip] `#{file}' already exists"
  elsif File.exists?(file.downcase)
    warn "[skip] `#{file.downcase}' exists, which could conflict with `#{file}'"
  else
    puts "[add] writing `#{file}'"
    File.open(file, "w") { |f| f.write(content) }
  end
end

create_file(File.join(ENV['HOME'], '.caprc'), caprc)

base = ARGV.shift
config_dir = File.join(base,'config')
if File.directory?(config_dir)
  files.each do |file, content|
    create_file(File.join(base, file), content)
  end
else
  warn "[warn] directory `#{config_dir}' does not exist"
  warn "[skip] '#{base}/Capfile'"
  warn "[skip] '#{base}/config/deploy.rb'"
end

puts "[done] depified!"
