#!/usr/bin/env ruby
#
@tests = 0

# Use ./integration REMOTE to use remote gem sources.
#
@remote = ARGV.include? 'REMOTE'

def remote?
  @remote
end

puts
puts "Running integration tests with #{remote?? 'REMOTE' : 'LOCAL'} gems."
puts

def bundle_options
  @remote ? '' : '--local'
end

def gem_options
  @remote ? '--remote' : '--local'
end

def each_type
  yield :full, 20
  yield :live, 0
end

def ask_server query
  `curl -S 'localhost:8080/books?query=#{query}&ids=20'`
end
def server query, match
  @tests += 1
  if ask_server(query).chomp.include?(match)
    puts "Yay, server returned #{match} for #{query}!"
  else
    fail "#{query} result does not include #{match}"
  end
end
def client query, match, port = 3210
  @tests += 1
  if `curl -S 'localhost:#{port}/search/full?query=#{query}&ids=20'`.chomp.include?(match)
    puts "Yay, client returned #{match} for #{query}!"
  else
    fail "#{query} result does not include #{match}"
  end
end

def install_all_in_one
  puts "Installing the Sinatra/Unicorn all_in_one client/server."
  system "picky generate all_in_one sandbox/server"
  system "cd sandbox/server; bundle install #{bundle_options}"
  system "cd sandbox/server; bundle exec rake index"
  system "cd sandbox/server; bundle exec unicorn -c unicorn.rb &"

  sleep 5 # loading
end

def install_sinatra_server
  # Note: Not using bundler anymore.
  #
  puts "Installing the Sinatra/Unicorn server."
  system "picky generate server sandbox/server"
  system "cd sandbox/server; bundle exec rake index"
  system "cd sandbox/server; bundle exec unicorn -c unicorn.rb &"

  sleep 5 # loading
end

def run_search_requests_on_server
  puts
  puts "Running search requests on the server"
  server "alan", "author"
  server "ALAN", "title"
  server "pinchn~", "pynchon"
  server "sp", "title"
  server "sp", "author"
  server "title:lyterature~+2002", "literature"
  puts
  puts
end

def install_sinatra_client
  puts "Installing the client."
  system "picky generate client sandbox/client"
  system "cd sandbox/client; bundle install #{bundle_options}"
  system "cd sandbox/client; unicorn -p 3210 &"

  sleep 5 # loading
end

def run_search_requests_on_client port = 3210
  sleep 3 # loading
  
  puts
  puts "Running search requests on the client directly"
  client "alan", "author", port
  client "ALAN", "title", port
  client "pinchn~", "pynchon", port
  client "sp", "title", port
  client "sp", "author", port
  client "title:lyterature~+2002", "literature", port
  client "alan", "Alan Turing", port
  puts
  puts
end

def open_client_in_browser port = 3210
  system "open -a 'Google Chrome' http://localhost:#{port}/?q=alan"
  sleep 1
  system "open -a 'Google Chrome' http://localhost:#{port}/?q=a%2A%20b"
  sleep 5
end

def run_server_integration_tests with_bundle_exec = true
  puts "Now the server integration specs"
  if system("cd sandbox/server; #{ 'bundle exec' if with_bundle_exec } rake spec")
    puts "Yay! Integration specs ran through!"
  else
    raise "Integration specs failed!"
  end
  sleep 1
end

def run_server_rake_task name
  unless system("cd sandbox/server; rake #{name} --trace")
    raise "Integration specs failed!"
  end
end

def run_server_rake_tasks
  puts "Now the server rake tasks"
  run_server_rake_task '-T'
  run_server_rake_task 'analyze'
  run_server_rake_task 'todo'
  run_server_rake_task 'try[test]'
end

def run_server_speed_tests
  puts "Now for a speed test"
  queries = ['alan', 'pinchn~', 'sp', 'title:lyterature~+2002'].cycle
  100.times do
    ask_server queries.next
  end
end

def run_statistics
  # system "picky stats sandbox/server/log/search.log &"
  # system "open -a 'Google Chrome' http://localhost:4567/"
end

def kill_server
  puts "Killing server (if there)"
  system "ps ax | grep '\\bunicorn' | awk '{print $1}' | xargs kill"
end

def kill_client
  puts "Killing client (if there)"
  system "ps ax | grep '\\bunicorn -p 3210' | awk '{print $1}' | xargs kill"
end

def delete_server_directory
  system "rm -r sandbox/server"
end

def delete_client_directory
  system "rm -r sandbox/client"
end

# Runs a whole integration.
#
begin
  puts "Please run using Ruby 1.9" if RUBY_VERSION < '1.9.0'

  kill_server
  kill_client
  
  system "./install #{ 'REMOTE' if remote? }"

  # All in one.
  #
  puts "\nALL IN ONE SERVER\n"

  install_all_in_one
  run_server_rake_tasks

  puts "\nALL IN ONE CLIENT\n"

  run_search_requests_on_client 8080 # Since it is just one server.
  open_client_in_browser 8080

  kill_server
  delete_server_directory

  # Sinatra Client.
  #
  puts "\nSINATRA CLIENT\n"

  install_sinatra_client

  # Sinatra Server.
  #
  puts "\nSINATRA SERVER\n"

  install_sinatra_server
  run_search_requests_on_server
  run_server_integration_tests false
  run_server_speed_tests
  run_server_rake_tasks

  run_search_requests_on_client
  open_client_in_browser

  run_statistics

  kill_server
  delete_server_directory

  puts
  puts "SUCCESS! #{@tests} tests run without a hitch :)"
  puts
rescue Exception => e
  puts system 'cd sandbox/server; cat log/unicorn.stderr.log'
  puts e.message
  puts e.backtrace
ensure
  puts "Press enter to kill (Break and have mercy with Ctrl-C)"
  gets() # () to not take ARGV

  kill_server
  kill_client

  delete_server_directory
  delete_client_directory
end