#!/usr/bin/env ruby

require "optparse"
require "pp"
require "yaml"

$:.unshift(File.join(File.dirname(__FILE__), "/../lib"))
require "solusvm"

opts = {}
$shell_methods = {}
$shell_methods['server-create'] = "<hostname> <password> -t myimage -k xen -p myplan -i 1"
$shell_methods['server-boot'] = "<vserverid>"
$shell_methods['server-reboot'] = "<vserverid>"
$shell_methods['server-shutdown'] = "<vserverid>"
$shell_methods['server-suspend'] = "<vserverid>"
$shell_methods['server-resume'] = "<vserverid>"
$shell_methods['server-status'] = "<vserverid>"
$shell_methods['server-addip'] = "<vserverid>"
$shell_methods['server-changeplan'] = "<vserverid> <newplan>"
$shell_methods['server-check-exists'] = "<vserverid>"
$shell_methods['server-terminate'] = "<vserverid>"
$shell_methods['node-stats'] = "<nodeid>"
$shell_methods['node-available-ips'] = "<nodeid>"
$shell_methods['server-rebuild'] = "<vserverid> -t myimage"

def list_commands
  puts "Commands:"
  puts $shell_methods.collect { |k,v| "  #{k} #{v}"}.join("\n")
  exit
end

op = OptionParser.new do |o|
  o.banner = "USAGE: #{File.basename($0)} <command> [options]"
  o.on("-I", "--api-login [id]", "API ID") do |opt|
    opts[:api_id] = opt
  end

  o.on("-K", "--api-key [key]", "API KEY") do |opt|
    opts[:api_key] = opt
  end

  o.on("-N", "--node [node]", "Node to provision on") do |opt|
    opts[:node] = opt
  end

  o.on("-U", "--api-url [URL]", "URL to the API") do |opt|
    opts[:api_url] = opt
  end

  o.on("-u", "--username [username]", "The client to put the VPS under") do |opt|
    opts[:username] = opt
  end

  o.on("-k", "--kind [kind]", "Type of VPS (#{Solusvm::Server::VALID_SERVER_TYPES.join(',')})") do |opt|
    opts[:kind] = opt
  end

  o.on("-t", "--template [template]", "VPS template to boot from") do |opt|
    opts[:template] = opt
  end

  o.on("-p", "--plan [plan]", "Plan to use") do |opt|
    opts[:plan] = opt
  end

  o.on("-i", "--ips [number]", "Number of ips to add to the VPS") do |opt|
    opts[:ips] = opt.to_i
  end

  o.on("-h", "--help", "Show help documentation") do |h|
    puts o
    list_commands
  end
end

optparse = op
op.parse!

config_file = File.join(File.expand_path(ENV['HOME']), '.solusvm.yml')
server = Solusvm::Server.new
general = Solusvm::General.new

if ARGV.empty?
  # STDERR.puts "USAGE: #{File.basename($0)} [function] [options]"
  puts optparse.help
  list_commands
else
  if File.exists?(config_file)
    config = YAML::load(File.open(config_file))
    Solusvm.config(config['id'], config['key'], :url => config['url'])
    opts[:username] = config['username'] unless opts[:username]
  elsif opts[:api_url] && opts[:api_id] && opts[:api_key]
    Solusvm.config(opts[:api_id], opts[:api_key], :url => opts[:api_url])
  else
    puts "Must supply the api id/key and URL"
    exit
  end
  meth = ARGV[0].chomp
  if $shell_methods.include?(meth)
    ARGV.shift
    if ARGV.empty?
      p $shell_methods[meth]
      exit
    else
      begin
        case meth
        when 'server-create'
          unless ARGV.size == 2
            list_commands
          end
          p server.create(ARGV[0], ARGV[1], :plan => opts[:plan], :ips => opts[:ips], :type => opts[:kind], 
                          :username => opts[:username], :template => opts[:template], :node => opts[:node])
        when 'server-status'
          p server.status(ARGV[0])
        when 'server-boot'
          p server.boot(ARGV[0])
        when 'server-reboot'
          p server.reboot(ARGV[0])
        when 'server-suspend'
          p server.suspend(ARGV[0])
        when 'server-resume'
          p server.resume(ARGV[0])
        when 'server-check-exists'
          p server.exists?(ARGV[0])
        when 'server-terminate'
          p server.terminate(ARGV[0])
        when 'node-available-ips'
          ips = general.node_available_ips(ARGV[0])
          if ips.any?
            puts ips.join("\n")
          else
            puts ips
          end
        when 'node-stats'
          stats = general.node_statistics(ARGV[0])
          stats.each do |k,v|
            puts "#{k} => #{v}"
          end
        when 'server-rebuild'
           p server.rebuild(ARGV[0], opts[:template])
        end
      rescue Exception => e
        puts "Error:  #{e}\n\n"
        puts "Backtrace: \n\n"
        puts e.backtrace.join("\n")
      end
    end
  else
    puts "#{meth} is not a valid function"
  end
end