require ‘optparse’

namespace :protractor do |args|

desc "starts protractor example test to see if you have your system set up correctly"
task :example do
  begin
    webdriver_pid = fork do
      Rake::Task["protractor:webdriver"].invoke
    end
    write_log "Waiting for test server and webdriver server to start"
    sleep 5
    file = File.expand_path('../../../spec/protractor_example.conf.js', __FILE__)
    system "protractor #{file}"
  ensure
    Rake::Task["protractor:kill_webdriver"].invoke
    Rake::Task["protractor:kill_selenium_processes"].invoke
  end
end

def write_log(message)
  return if ENV['nolog'].present?
  puts message
end

desc "Run specs from config file"
task :spec do
  begin
    options = ''
    OptionParser.new(args) do |opts|
      # Test specific spec files instead of a whole suite.
      specsKey = '--specs'
      opts.on("#{specsKey} {filename}", 'Test spec files', String) do |filename|
        options = options + "#{specsKey} #{filename}"
      end
      # Suite setup
      suiteKey = '--suite'
      opts.on("#{suiteKey} {suite}", 'Test suite name', String) do |suite|
        options = options + "#{suiteKey} #{suite}"
      end

      opts.on("--debug", String) do
        options = options + "debug"
      end
    end.parse!

    options += "--specs #{ENV['SPECS']}" if ENV['SPECS'].present?
    options += "--suite #{ENV['SUITE']}" if ENV['SUITE'].present?
    options += "debug" if ENV['DEBUG'].present?

    webdriver_pid = fork do
      [$stdout,$stderr].each { |fh| fh.reopen File.open("/dev/null","w") } if ENV['nolog'].present? || ENV['nolog_selenium'].present?
      Rake::Task['protractor:webdriver'].invoke
    end
    rails_server_pid = fork do
      [$stdout,$stderr].each { |fh| fh.reopen File.open("/dev/null","w") } if ENV['nolog'].present? || ENV['nolog_rails'].present?
      Rake::Task['protractor:rails'].invoke
    end
    write_log "webdriver PID: #{webdriver_pid}"
    write_log "Rails Server PID: #{rails_server_pid}".yellow.bold
    write_log "Waiting for servers to finish starting up...."
    sleep Protractor.configuration.startup_timeout
    cmd = "protractor #{options} #{Protractor.configuration.config_path}/#{Protractor.configuration.config_file}"
    write_log cmd
    success = system cmd
    write_log "Protractor has failed to run test with options '#{options}'".red.bold unless success
    Process.kill 'TERM', webdriver_pid
    Process.kill 'TERM', rails_server_pid
    Process.wait webdriver_pid
    Process.wait rails_server_pid
    write_log "Waiting to shut down cleanly.........".yellow.bold
    sleep 5
  rescue Exception => e
    puts e
  ensure
    Rake::Task["protractor:kill"].invoke
    exit 1 unless success
  end
end

task :spec_and_cleanup => [:spec, :cleanup]

task :kill do
  write_log "killing running protractor processes".green.bold
  Rake::Task["protractor:kill_rails"].invoke
  Rake::Task["protractor:kill_webdriver"].invoke
  Rake::Task["protractor:kill_selenium_processes"].invoke
end

task :kill_selenium_processes do
  write_log "kill left over selenium processes...".yellow
  system "ps aux | grep -ie 'protractor\/selenium' | grep -v grep | awk '{print $2}' | xargs kill -9"
end

task :kill_webdriver do
  write_log "kill webdriver server...".yellow
  system "ps aux | grep -ie '\-Dwebdriver' | grep -v grep | awk '{print $2}' | xargs kill -9"
end

task :kill_rails do
  write_log "kill protractor rails tests server...".yellow
  system "kill `cat tmp/pids/protractor_test_server.pid`"
end

task :rails do
  env = ENV['PROTRACTOR_SERVER_ENV'] ||= 'test'
  server = Protractor.configuration.server
  write_log "Starting Rails server #{server} on port #{Protractor.configuration.port} environement #{env} pid file in tmp/pids/protractor_test_server.pid".green
  rails_command = "rails s #{server} -e #{env} -P tmp/pids/protractor_test_server.pid --port=#{Protractor.configuration.port}"
  if ENV['rails_binding'] != nil
    rails_command << " --binding #{ ENV['rails_binding'] }"
  end
  system rails_command
end

task :webdriver do
  write_log "Starting selenium server".green
  system "webdriver-manager start --standalone"
end

task :cleanup do
  write_log "rake db:test:prepare to cleanup for the next test session".green
  system 'rake db:test:prepare --trace'
  write_log "Seeding the test database....".green
  system "rake db:test:seed --trace"
end

end

namespace :db do

namespace :test do
  desc "seed only the test database (Task provided by protractor-rails)"
  task :seed do
    system "rake db:seed RAILS_ENV=test"
  end
end

end