# Capture and encapsulate the command-line options, then
# allow read-only access to the state (since the command-line cannot change
# after the program starts).
# The main app will contain a single instance of this class.  
#

require "getoptlong"

class Clo

  include Singleton

  # List elements here to allow read access
  #
  attr_reader :mission_list_file, :sim, :warp, :stat_interval, :check_interval, \
  :monitor_threads
  
  # Initialize all the elements to default states
  #
  def initialize

    # mission specs
    @mission_list_file = nil
    @sim = false
    @warp = false

    # modem specs
    @stat_interval = 600
    @check_interval = 120
  end

  def usage
    puts("Rover main program\nusage:")
    s = "  ruby main.rb {--cfg-list | -f} filename [--sim | -s] [--warp | -w] \n" +
      "               [--monitor | -m] [--stat seconds] [--check seconds] \n" +
      "               [--help | -h | -?]"
    puts(s)
    puts("  [{--cfg-list | -f} file]  Mission list file (required argument)")
    puts("  [--sim | -s]              Run in simulation mode")
    puts("  [--warp | -w]             Warp extended wait times to 1 second")
    puts("  [--monitor | -m]          Monitor threads")
    puts("  [--stat]                  Seconds between vehicle status msgs (#{@stat_interval})")
    puts("  [--check]                 Seconds between abort msg checks (#{@check_interval})")
    puts("  [--help | -h | -?]        Print this usage text")
  end
    
  # Uses Ruby GetoptLong class to parse command-line. Set state of
  # elements based on values and switches on the command-line.
  # 
  def parse
  
    # List expected/allowed command-line options here
    #
    opts = GetoptLong.new(
      ["--cfg-list",     "-f",  GetoptLong::REQUIRED_ARGUMENT],
      ["--sim",          "-s",  GetoptLong::NO_ARGUMENT],
      ["--warp",         "-w",  GetoptLong::NO_ARGUMENT],
      ["--monitor",      "-m",  GetoptLong::NO_ARGUMENT],
      ["--stat",         "-t",  GetoptLong::REQUIRED_ARGUMENT],
      ["--check",        "-c",  GetoptLong::REQUIRED_ARGUMENT],
      ["--help",   "-?", "-h",  GetoptLong::NO_ARGUMENT]
    )

    # Iterate through options, set state of elements
    #
    opts.each do |opt, argm|
      case opt
        # Save specified config file name, raise exception if file nonexistant
        #
        when '--cfg-list'
          @mission_list_file = argm
          unless (File.file?(@mission_list_file))
            raise("Exception! Specified config file not found: #{@mission_list_file}")
          end

        # Get simulation, monitor, and warp flags
        #
        when '--sim'
          @sim = true
        when '--warp'
          @warp = true
        when '--monitor'
          @monitor_threads = true

	# Get status and command intervals
	#
	when '--stat'
	  @stat_interval = argm.to_f
	  unless (@stat_interval > 0)
	    raise("Exception! Status interval must be > 0: #{@stat_interval}")
	  end
	when '--check'
	  @check_interval = argm.to_f
	  unless (@check_interval > 0)
	    raise("Exception! Check interval must be > 0: #{@check_interval}")
	  end

        when '--help'
          usage
          exit
      end
    end

  end
  
  # Create and return summary string
  #
  def to_s
    s = ""
    s += "  :Mission list file = "
    s += "#{@mission_list_file}\n" if     @mission_list_file
    s += "none\n" unless @mission_list_file
    s += "  :Sim = #{@sim}\n"
    s += "  :Warp time = #{@warp}\n"
    s += "  :Status report interval = #{@stat_interval} seconds\n"
    s += "  :Modem command check interval = #{@check_interval} seconds\n"
    s
  end  

end
