# use this for local installs
SOURCE=ENV['SOURCE'] || 'http://github.com/pixels-and-bits/strappy/raw/master'

def gen(what)
  run "./script/rails g #{what}"
end

def file_append(file, data)
  log :append, file
  File.open(file, 'a') {|f| f.write(data) }
end

def file_inject(file_name, sentinel, string, before_after=:after)
  log :inject, file_name
  gsub_file file_name, /(#{Regexp.escape(sentinel)})/mi do |match|
    if :after == before_after
      "#{match}\n#{string}"
    else
      "#{string}\n#{match}"
    end
  end
end

def file_str_replace(file_name, sentinel, replacement)
  log :gsub, file_name
  gsub_file file_name, /(#{Regexp.escape(sentinel)})/mi do |match|
    replacement
  end
end

if 'true' == ENV['INTEGRITY']
  sudo = 'y'
end

# Git
file_append '.gitignore', open("#{SOURCE}/gitignore").read
git :init
git :add => '.gitignore'
run 'rm -f public/images/rails.png'
run 'cp config/database.yml config/database.template.yml'
git :add => "."
git :commit => "-am 'Initial commit'"

# install Gemfile and gems
run 'rm Gemfile'

file 'Gemfile', <<-EOGEMS
source 'http://rubygems.org'
source 'http://gems.github.com'

gem 'rails', '3.0.0.beta2'
gem 'authlogic', :git => 'git://github.com/binarylogic/authlogic.git'
gem 'capistrano', '2.5.18'
gem 'capistrano-ext', '1.2.1'
gem 'config_reader', '0.0.7'
gem 'friendly_id', '2.2.7'
gem 'formtastic', :git => 'git://github.com/justinfrench/formtastic.git'
gem 'haml', '2.2.21'
gem 'hoe', '2.5.0'
gem 'mongrel'
gem 'mysql'
gem 'seed-fu', '1.2.3'
gem 'test-unit', '1.2.3'
gem 'will_paginate', '2.3.12'

group :test do
  gem 'webrat'
  gem 'cucumber'
  gem 'cucumber-rails'
  gem 'database_cleaner'
  gem 'faker'
  gem 'launchy'
  gem 'machinist'
  gem 'pickle'
  gem 'rcov'
  gem 'rspec-rails', '>= 2.0.0.beta.1'
end
EOGEMS

run 'bundle install'
git :add => "."
git :commit => "-am 'Add Gemfile, install gems'"

# CoreExtensions
plugin 'core_extensions',
  :git => 'git://github.com/UnderpantsGnome/core_extensions.git'
git :add => "."
git :commit => "-am 'Added Core Extensions'"

# install strappy rake tasks
rakefile 'strappy.rake', open("#{SOURCE}/lib/tasks/strappy.rake").read

# # install haml rake tasks
# rakefile 'haml.rake', open("#{SOURCE}/lib/tasks/haml.rake").read
# 
# # install seed_fu rake tasks
# rakefile 'seed_fu.rake', open("#{SOURCE}/lib/tasks/seed_fu.rake").read
# 
# # install rcov rake tasks
# rakefile 'rcov.rake', open("#{SOURCE}/lib/tasks/rcov.rake").read

# RSpec
gen 'rspec:install'
# file 'spec/rcov.opts', open("#{SOURCE}/spec/rcov.opts").read
file_append('spec/spec_helper.rb', open("#{SOURCE}/spec/helpers.rb").read)
git :add => "."
git :commit => "-am 'Added RSpec'"

# Cucumber
gen 'cucumber:skeleton --rspec --webrat'

file_str_replace('config/cucumber.yml', 
  %q{rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""},
  %q{rerun = ""}
)

# file_inject('/spec/spec_helper.rb',
#   "require 'authlogic/test_case'",
#   "require 'webrat'
# 
# Webrat.configure do |config|
#   config.mode = :rails
# end",
#   :after
# )

git :add => "."
git :commit => "-am 'Added Cucumber'"

# 
# SiteConfig
file 'config/site.yml', open("#{SOURCE}/config/site.yml").read
lib 'site_config.rb', open("#{SOURCE}/lib/site_config.rb").read
git :add => "."
git :commit => "-am 'Added SiteConfig'"

# # CC.rb
# rakefile('cruise.rake') { open("#{SOURCE}/lib/tasks/cruise.rake").read }
# git :add => "."
# git :commit => "-am 'Added cruise rake task'"

# Capistrano
capify!
file 'config/deploy.rb', open("#{SOURCE}/config/deploy.rb").read

%w( production staging ).each do |env|
  file "config/deploy/#{env}.rb", <<-EOC
set :rails_env, "#{env}"
set :branch, "#{env}"
EOC

end

inside('config/environments') do
  run 'cp development.rb staging.rb'
end

git :add => "."
git :commit => "-am 'Added Capistrano config'"

run 'echo N\n | haml --rails .'
run 'mkdir -p public/stylesheets/sass'
%w(
  application
  print
  _colors
  _common
  _flash
  _forms
  _grid
  _helpers
  _reset
  _typography
).each do |file|
  file "public/stylesheets/sass/#{file}.sass",
    open("#{SOURCE}/public/stylesheets/sass/#{file}.sass").read
end
git :add => "."
git :commit => "-am 'Added Haml and Sass stylesheets'"

# jRails
plugin 'jrails', :svn => 'http://ennerchi.googlecode.com/svn/trunk/plugins/jrails'

# remove the installed files, we're using a newer version below
inside('public/javascripts') do
  %w(
    jquery-ui.js
    jquery.js
  ).each do |file|
    run "rm -f #{file}"
  end
end

git :add => "."
git :commit => "-am 'Added jRails plugin'"

# jQuery

# clean up prototype files
inside('public/javascripts') do
  %w(
    application.js
    controls.js
    dragdrop.js
    effects.js
    prototype.js
  ).each do |file|
    run "rm -f #{file}"
  end
end

file 'public/javascripts/jquery.js',
  open('http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js').read
file 'public/javascripts/jquery-ui.js',
  open('http://ajax.googleapis.com/ajax/libs/jqueryui/1.7/jquery-ui.min.js').read
file 'public/javascripts/jquery.form.js',
  open('http://github.com/malsup/form/raw/master/jquery.form.js').read
file 'public/javascripts/application.js',
  open("#{SOURCE}/public/javascripts/application.js").read

git :add => "."
git :commit => "-am 'Added jQuery with UI and form plugin'"

# Blackbird
run 'mkdir -p public/blackbird'
file 'public/blackbird/blackbird.js',
  open('http://blackbirdjs.googlecode.com/svn/trunk/blackbird.js').read
file 'public/blackbird/blackbird.css',
  open('http://blackbirdjs.googlecode.com/svn/trunk/blackbird.css').read
file 'public/blackbird/blackbird.png',
  open('http://blackbirdjs.googlecode.com/svn/trunk/blackbird.png').read

git :add => "."
git :commit => "-am 'Added Blackbird'"

# uberkit
plugin 'uberkit', :git => 'git://github.com/mbleigh/uberkit.git'

# git :add => "."
# git :commit => "-am 'Added uberkit plugin'"

git :add => "."
git :commit => "-am 'Added Haml and Sass stylesheets'"

# add bundle-fu
plugin 'bundle-fu',
  :git => 'git://github.com/timcharper/bundle-fu.git'
git :add => "."
git :commit => "-am 'Added bundle-fu'"

# Setup Authlogic
# rails gets cranky when this isn't included in the config
gen 'session user_session'

# allow login by login or pass
file_inject('/app/models/user_session.rb',
  "class UserSession < Authlogic::Session::Base",
  "  find_by_login_method :find_by_login_or_email",
  :after
)

gen 'rspec_controller user_sessions'
gen 'scaffold user'

# get rid of the gend templates
Dir.glob('app/views/users/*.erb').each do |file|
  run "rm #{file}"
end
run "rm app/views/layouts/users.html.erb"

gen 'controller password_reset'

route <<-EOROUTES
  root :to => 'home#index'

  match 'admin',
    :as => :admin,
    :to => 'admin/base#index'

  match 'login',
    :as => :login,
    :to => 'user_sessions#new'

  match 'logout',
    :as => :logout,
    :to => 'user_sessions#destroy'

  match 'signup',
    :as => :signup,
    :to => 'users#new'

  match 'forgot_password',
    :as => :forgot_password,
    :to => 'password_reset#new'

  resource :account, :controller => "users"
  resource :user_session

  resources :password_reset
  resources :users
EOROUTES

# migrations
file Dir.glob('db/migrate/*_create_users.rb').first,
  open("#{SOURCE}/db/migrate/create_users.rb").read

# models
%w( user notifier ).each do |name|
  file "app/models/#{name}.rb",
    open("#{SOURCE}/app/models/#{name}.rb").read
end

# controllers
%w( user_sessions password_reset users ).each do |name|
  file "app/controllers/#{name}_controller.rb",
    open("#{SOURCE}/app/controllers/#{name}_controller.rb").read
end

# views
%w(
  notifier/password_reset_instructions.erb
  password_reset/edit.html.haml
  password_reset/new.html.haml
  user_sessions/new.html.haml
  users/_form.haml
  users/edit.html.haml
  users/new.html.haml
  users/show.html.haml
).each do |name|
  file "app/views/#{name}", open("#{SOURCE}/app/views/#{name}").read
end

# fixtures
file "db/fixtures/users.rb", open("#{SOURCE}/db/fixtures/users.rb").read

# testing goodies
file_inject('/spec/spec_helper.rb',
  "require 'spec/rails'",
  "require 'authlogic/test_case'\n",
  :after
)

# specs
run 'mkdir -p spec/fixtures'

%w(
  fixtures/users.yml
  helpers/application_helper_spec.rb
  controllers/password_reset_controller_spec.rb
  controllers/user_sessions_controller_spec.rb
  controllers/users_controller_spec.rb
  models/user_spec.rb
  views/home/index.html.haml_spec.rb
).each do |name|
  file "spec/#{name}", open("#{SOURCE}/spec/#{name}").read
end
git :add => "."
git :commit => "-am 'Added specs'"

# features
%w(
  admin/admin_base.feature
  application/application_base.feature
  home/home.feature
  users/users.feature
  step_definitions/_common_steps.rb
  step_definitions/_custom_web_steps.rb
  step_definitions/user_steps.rb
  support/blueprints.rb
  support/paths.rb
).each do |name|
  file "features/#{name}", open("#{SOURCE}/features/#{name}").read
end

git :add => "."
git :commit => "-am 'Added features'"

route "map.forgot_password '/forgot_password',
  :controller => 'password_reset',
  :action => 'new'"

rake('db:migrate')
git :add => "."
git :commit => "-am 'Added Authlogic'"

# Add ApplicationController
file 'app/controllers/application_controller.rb',
  open("#{SOURCE}/app/controllers/application_controller.rb").read

# Add in the :xhr mime type
file_inject('/config/initializers/mime_types.rb',
  '# Be sure to restart your server when you modify this file.',
  'Mime::Type.register_alias "text/html", :xhr',
  :after
)

git :add => "."
git :commit => "-am 'Added ApplicationController'"

# Add ApplicationHelper
file 'app/helpers/application_helper.rb',
  open("#{SOURCE}/app/helpers/application_helper.rb").read
git :add => "."
git :commit => "-am 'Added ApplicationHelper'"

# Add Layout
%w(
  application.html.haml
  _body.html.haml
  _common_headers.html.haml
  _footer.html.haml
  _on_ready.html.haml
).each do |name|
  file "app/views/layouts/#{name}",
    open("#{SOURCE}/app/views/layouts/#{name}").read
end

git :add => "."
git :commit => "-am 'Added Layout and templates'"

# setup admin section
%w(
  app/controllers/admin
  app/views/admin/base
  spec/controllers/admin
  app/helpers/admin
).each do |dir|
  run "mkdir -p #{dir}"
end

file "app/views/layouts/admin.html.haml",
  open("#{SOURCE}/app/views/layouts/admin.html.haml").read
file "app/views/admin/base/index.html.haml",
  open("#{SOURCE}/app/views/admin/base/index.html.haml").read
file "app/controllers/admin/base_controller.rb",
  open("#{SOURCE}/app/controllers/admin/base_controller.rb").read
file "spec/controllers/admin/base_controller_spec.rb",
  open("#{SOURCE}/spec/controllers/admin/base_controller_spec.rb").read
file "app/helpers/admin/base_helper.rb",
  open("#{SOURCE}/app/helpers/admin/base_helper.rb").read

route "map.admin '/admin', :controller => 'admin/base'"

git :add => "."
git :commit => "-am 'Added admin stubs'"

# Remove index.html and add HomeController
git :rm => 'public/index.html'
gen :rspec_controller, 'home'
route "map.root :controller => 'home'"

file 'app/views/home/index.html.haml',
  open("#{SOURCE}/app/views/home/index.html.haml").read

file "app/helpers/home_helper.rb",
  open("#{SOURCE}/app/helpers/home_helper.rb").read

file "spec/views/home/index.html.haml_spec.rb",
  open("#{SOURCE}/spec/views/home/index.html.haml_spec.rb").read

file "spec/controllers/home_controller_spec.rb",
  open("#{SOURCE}/spec/controllers/home_controller_spec.rb").read

git :add => "."
git :commit => "-am 'Removed index.html. Added HomeController'"

# Add ApplicationController
file 'app/controllers/application_controller.rb',
  open("#{SOURCE}/app/controllers/application_controller.rb").read

git :add => "."
git :commit => "-am 'Added ApplicationController'"

# Application Layout
file 'app/views/layouts/application.html.haml',
  open("#{SOURCE}/app/views/layouts/application.html.haml").read

git :add => "."
git :commit => "-am 'Added Layout'"

# update the readme
run 'rm README'
file 'README.textile', open("#{SOURCE}/README.textile").read
git :add => "."
git :commit => "-am 'Replaced README'"

# Add Action images
%w(
  add.png
  arrow_up_down.png
  delete.png
  pencil.png
  user_edit.png
).each do |name|
  file "public/images/#{name}",
    open("#{SOURCE}/public/images/#{name}").read
end

git :add => "."
git :commit => "-am 'Added Action images'"

# cleanup gend tests
run 'rm -rf test'
git :add => "."
git :commit => "-am 'removed gend tests'"

rake 'db:seed'

puts "\n#{'*' * 80}\n\n"
puts "All done. Enjoy."
puts "\n#{'*' * 80}\n\n"
