#!/usr/bin/ruby1.8
#
# NAME
#  custodian-enqueue - Insert sentinel-probes into a queue.
#
# SYNOPSIS
#  custodian-enqueue  [ -h | --help ]
#                     [ -m | --manual]
#                     [ -f | --file FILE]
#                     [ -d | --dump ]
#                     [    | --test ]
#                     [ -t | --timeout N ]
#
# OPTIONS
#
#  -h, --help          Show a help message, and exit.
#
#  -m, --manual        Show this manual, and exit.
#
#  -d, --dump          Dump the generated JSON to the console; don't insert in the queue.
#
#  --test              Test the parsing of the given file, alert on errors.
#
#  -f, --file FILE     Parse the given configuration file.
#
#  -t, --timeout N     Specify the timeout period for the tests.
#
#
# ABOUT
#
#  This tool reads a single configuration file and parses it into a
# series of network & protocol tests.   These tests are serialized
# into JSON, and stored in a beanstalkd queue.
#
#  The intention is that the tests will be pulled from the queue and
# executed by the companion program custodian-dequeue.  The dequeing
# process may occur up numerous other hosts
#
# CONFIGURATION FILE
#
#  The configuration file is 99% compatible with that used in the tool
# custodian replaces.
#
#
# AUTHOR
#
#  Steve Kemp  <steve@bytemark.co.uk>
#



#
#  Modules we require
#
require 'beanstalk-client'
require 'custodian/parser'
require 'getoptlong'



#
#  Entry-point to our code.
#
if __FILE__ == $0 then

  $help   = false
  $manual = false
  $SERVER = "127.0.0.1:11300"

  begin
    opts = GetoptLong.new(
                          [ "--dump",  "-d", GetoptLong::NO_ARGUMENT ],
                          [ "--test",   GetoptLong::NO_ARGUMENT ],
                          [ "--server",   GetoptLong::REQUIRED_ARGUMENT ],
                          [ "--file",  "-f", GetoptLong::REQUIRED_ARGUMENT ],
                          [ "--help",  "-h", GetoptLong::NO_ARGUMENT ],
                          [ "--manual","-m", GetoptLong::NO_ARGUMENT ],
                          [ "--timeout","-t", GetoptLong::REQUIRED_ARGUMENT ]
                          )
    opts.each do |opt, arg|
      case opt
      when "--dump" then
          ENV["DUMP"] = "1"
      when "--test" then
          ENV["TEST"] = "1"
      when "--server" then
          $SERVER = arg
      when "--file" then
          ENV["FILE"] = arg
      when "--timeout" then
          ENV["TIMEOUT"] = arg
      when "--help" then
          $help = true
      when "--manual" then
          $manual = true
      end
    end
  rescue StandardError => ex
    puts "Option parsing failed: #{ex.to_s}"
    exit
  end


  #
  # CAUTION! Here be quality kode.
  #
  if $manual or $help

    # Open the file, stripping the shebang line
    lines = File.open(__FILE__){|fh| fh.readlines}[1..-1]

    found_synopsis = false

    lines.each do |line|

      line.chomp!
      break if line.empty?

      if $help and !found_synopsis
        found_synopsis = (line =~ /^#\s+SYNOPSIS\s*$/)
        next
      end

      puts line[2..-1].to_s

      break if $help and found_synopsis and line =~ /^#\s*$/

    end

    exit 0
  end


  #
  # Connected to the server
  #
  queue = Beanstalk::Pool.new([$SERVER])
  if ( ! queue )
    puts "Failed to connect to beanstalk server: #{$SERVER}"
    exit 1
  end


  #
  # Create the parser
  #
  mon = MonitorConfig.new( ENV['FILE'] )

  #
  # Set the timeout
  #
  if ( !ENV['TIMEOUT'].nil? )
     mon.set_timeout( ENV['TIMEOUT'] )
  end

  #
  # Run the parser - and get callbacks when a new job is added.
  #
  mon.parse_file do |test|

    if ( ENV['TEST'] )
      # nop
    elsif ( ENV['DUMP'] )
      puts test.to_json
    else
      queue.put( test.to_json )
    end
  end


  #
  # If there were errors then we'll not get this far.
  #
  if ( File.exists?( "/etc/mauvealert/mauvesend.destination" ) )

    #
    # Inititate a heartbeat
    #
    system( "mauvesend alert.bytemark.co.uk -i custodian-enqueue -c now -r +10m -s \"heartbeat failed for custodian-enqueue.\" --detail=\"<p>The heartbeat wasn't sent for custodian-enqueue - This means that new tests are not being pushed into the <tt>beanstalkd</tt> queue, and our monitoring is potentially broken</p>\" " )
  end


end