#!/usr/bin/env ruby
#
#  Created by Bodaniel Jeanes on 2008-8-19.
#  Copyright (c) 2008. All rights reserved.

require File.expand_path(File.dirname(__FILE__) + '/../lib/ghost')
require 'open-uri'

def help_text(exit_code = 0)
  script_name = File.basename $0
  puts """USAGE: #{script_name} add <hostname> [<ip=127.0.1.1>]
       #{script_name} modify <hostname> <ip> OR <hostname> (will lookup ip)
       #{script_name} delete <hostname>
       #{script_name} delete_matching <pattern>
       #{script_name} list [<filter>]
       #{script_name} empty
       #{script_name} export
       #{script_name} import <file>
"""
  exit(exit_code)
end

begin
  if ARGV.size.zero? || ['-h', '--help', 'help'].include?(ARGV.first)
    help_text
  else
    case ARGV[0]
    when 'add'
      if [2,3].include?(ARGV.size)
        begin
          ARGV.shift
          host = Ghost::Host.add(*ARGV)
          puts "  [Adding] #{host.name} -> #{host.ip}"
          exit 0
        rescue SocketError
          $stderr.puts "Cannot find IP for host"
          exit 3
        rescue Ghost::RecordExists
          $stderr.puts "Cannot overwrite an existing entry. Use the modify subcommand"
          exit 3
        end
      else
        $stderr.puts "The add subcommand requires at least a hostname.\n\n"
        help_text 2
      end
    when 'modify'
      if ARGV.size == 3
        ARGV.shift
        ARGV << true
        host = Ghost::Host.add(*ARGV)
        puts "  [Modifying] #{host.name} -> #{host.ip}"
        exit 0
      else
        $stderr.puts "The modify subcommand requires a hostname and an IP.\n\n"
        help_text 4
      end
    when 'delete', 'del', 'remove', 'rm'
      if ARGV.size == 2
        Ghost::Host.delete(ARGV[1])
        puts "  [Deleting] #{ARGV[1]}"
        exit 0
      else
        $stderr.puts "The delete subcommand requires a hostname.\n\n"
        help_text 2
      end
    when 'delete_matching'
      if ARGV.size == 2
        matched = Ghost::Host.delete_matching(ARGV[1])
        if matched.empty?
          puts "  No matching entries found"
        else
          matched.each { |h| puts "  [Deleting] #{h}" }
        end
        exit 0
      else
        $stderr.puts "The delete_matching subcommand requires a hostname pattern.\n\n"
        help_text 2
      end
    when 'list'
      filter = %r|#{ARGV[1]}| if ARGV.size == 2

      hosts = Ghost::Host.list

      if filter
        hosts.reject! { |host| host.name !~ filter && host.ip !~ filter }
      end

      pad = hosts.max{|a,b| a.to_s.length <=> b.to_s.length }.to_s.length

      puts "Listing #{hosts.size} host(s):"

      hosts.each do |host|
        puts "#{host.name.rjust(pad+2)} -> #{host.ip}"
      end
      exit 0
    when 'empty'
      print "  [Emptying] "
      Ghost::Host.empty!
      puts "Done."
      exit 0
    when 'export'
      hosts = Ghost::Host.list
      hosts.each do |host|
        puts "#{host.name} #{host.ip}"
      end
      exit 0
    when 'import'
      if ARGV.size == 2
        begin
          import_file = open(ARGV[1])
          import_file.each_line do |line|
            host_infos = line.strip.split(' ', 2)
            host = Ghost::Host.add(*host_infos)
            puts "  [Adding] #{host.name} -> #{host.ip}"
          end
          exit 0
        rescue
          $stderr.puts "Cannot import. A problem occured while opening the import file."
          exit 5
        end
      else
        $stderr.puts "The import command requires an input file.\n\n"
        help_text 6
      end
    else
      $stderr.puts "Invalid option: #{ARGV[0]}"
      help_text 1
    end
  end
rescue Errno::EACCES
  $stderr.puts "Please re-run as root or using sudo"
  exit 3
end
