#!/usr/bin/env ruby
Dir[File.dirname(__FILE__) + '/../vendor/*'].each do |dir|
      $: << dir + '/lib'
end

require 'rubygems'
require 'net/ssh'
require 'net/sftp'
require 'term/ansicolor'
require 'mixlib/cli'

class String
  include Term::ANSIColor
end

class MyCLI
  include Mixlib::CLI

  option :user,
    :short => '-u USER',
    :long => "--user USER",
    :description => "SSH user to login with (Default root)",
    :default => 'root'

  option :password,
    :short => '-p PASS',
    :long => "--password PASS",
    :description => "SSH password to login with"
  
  option :host,
    :long => "--host HOST",
    :description => "Abiquo host IP to test"
  
  option :local,
    :long => "--local",
    :description => "Run the tests locally",
    :boolean => true
  
  option :help,
    :short => "-h",
    :long => "--help",
    :description => "Show this message",
    :on => :tail,
    :boolean => true,
    :show_options => true,
    :exit => 0

end

def required_option(cli, opt)
  if cli.config[opt].nil?
    $stderr.puts "\n#{opt.to_s} argument requied.\n\n"
    $stderr.puts cli.opt_parser.help
    exit 1
  end
  return cli.config[opt]
end

Log = Logger.new($stdout)
$stdout.sync = true

cli = MyCLI.new
cli.parse_options

TESTS_DIR = File.dirname(__FILE__) + '/../tests/'

if cli.config[:local]
  #Run the tests local
  puts "Running the test locally..."
  Dir.chdir TESTS_DIR
  output = ""
  `ruby abiquo_postinst_test.rb`.each_line do |l|
    output += l
    puts l
  end
  if output =~ /(Failure|Error)/m
    puts "\n>>>>>> TEST FAILED! <<<<<<\n\n".bold.red
  else
    puts "\n>>>>>> TEST OK <<<<<<\n\n".bold.green
  end
else
  required_option cli, :password
  required_option cli, :host

  begin
    print "Checking pre-requisites... "
    Net::SSH.start(cli.config[:host], cli.config[:user], :paranoid => false, :password => cli.config[:password]) do |ssh|
      ssh.exec!("rm -rf /tmp/tests")
      #ssh.exec!("which gem || yum install -y rubygems --exclude ruby-ee")
      #ssh.exec!("gem install --no-ri --no-rdoc term-ansicolor iniparse")
    end
    puts "Done".green.bold
  rescue Net::SSH::AuthenticationFailed => e
    $stderr.puts "Error connecting to the host. Authentication failed."
    exit 1
  rescue Exception => e
    $stderr.puts "Error cleaning previous tests in host #{cli.config[:host]}: #{e.message} #{e.class}"
    $stderr.puts $@
    $stderr.puts $!
    exit 1
  end

  begin
    print "Uploading tests... "
    Net::SFTP.start(cli.config[:host], 'root', :password => cli.config[:password], :paranoid => false) do |sftp|
      sftp.upload! TESTS_DIR, '/tmp/tests/'
    end
    puts "Done".green.bold
  rescue Exception => e
    $stderr.puts "Error uploading tests to host #{cli.config[:host]}: #{e.message}"
    exit 1
  end

  begin
    Net::SSH.start(cli.config[:host], 'root', :password => cli.config[:password], :paranoid => false) do |ssh|
      puts "Running tests..."
      output = ""
      ssh.exec!("cd /tmp/tests/ && ruby abiquo_postinst_test.rb") do |ch, stream, data|
        print data
        output += data
      end
      if output =~ /(Failure|Error)/m
        puts "\n>>>>>> TEST FAILED! <<<<<<\n\n".bold.red
      else
        puts "\n>>>>>> TEST OK <<<<<<\n\n".bold.green
      end
    end
  rescue Exception => e
    $stderr.puts "Error running tests in remote host #{cli.config[:host]}: #{e.message}"
    exit 1
  end
end
