#!/bin/env python
""" gschedpprint
Group Scheduling Configuration Pretty Printer

@author: Dillon Hicks
@organization: KUSP
@contact: kusp[at]googlegroups[dot]com
@contact: hhicks[at]ittc[dot]ku[dot]edu
@version: 1.0
@summary: Pretty prints a Group Scheduling Hierarchy
    configuration file (.gsh) in a more human friendly form 
    by stripping the extra data from it to show only the 
    group-member hierarchy.
    
    (g) some-group
        (t) some-grou-child-task
    (g) another-group

    ...

"""

import sys
import struct
import optparse
from pygsched.gsstructures import *
import pygsched.gsprocutils as gsproc
from pykusp.configutility import *

########################################################
#
# If this module is called as a command, then open the
# file, parse it, and 

if __name__ == "__main__":
    # imports required if this module is called as a
    # command
    import optparse, sys
    from pprint import *

    # Define the set of permitted parameters, including the
    # command arguments.  The initialization method creates
    # the parser and defines the defaults. The parse()
    # method actually parses the arguments one the command
    # line. This was done so that the instance of the class
    # could be global and thus available to all
    # routines. and then parse the arguments to this call
    # according to the specification
    class Params_Set:
        USAGE = "usage: %prog [options]"

        def __init__(self):
            # Create the argument parser and then tell it
            # about the set of legal arguments for this
            # command. The parse() method of this class
            # calls parse_args of the optparse module
            self.p = optparse.OptionParser(usage=self.USAGE)

            # Boring and totally standard verbose and
            # debugging options that should be common to
            # virtually any command
            #
            self.p.add_option("-d", action="store_const", const=1,        
                              dest="debug_level", 
                              help="Turn on diagnostic output at level 1")
            self.p.add_option("-D", action="store", type ="int",    
                              dest="debug_level", 
                              help="Turn on diagnostic output at level DEBUG_LEVEL")
            self.p.add_option("-v", action="store_const", const=1,        
                              dest="verbose_level", 
                              help="Turn on narrative output at level 1")
            self.p.add_option("-V", action="store", type ="int",    
                              dest="verbose_level", 
                              help="Turn on narrative output at level VERBOSE_LEVEL")
            
            # Command specific options. We can specify a
            # configuration file to parse, which defaults to
            # stdin, and an output file name, which defaults
            # to stdout.
            self.p.add_option("-c", action="store", type ="string", 
                              dest="configfile_name", 
                              help="Parse the file CONFIGFILE_NAME, over-riding stdin default")

         
            self.p.add_option("-p", action="store_const", const=True,        
                              dest="use_proc", 
                              help="Setting USE_PROC will pretty print the current hierarchy in /proc/group_sched")


        
            # Now tell the parser about the default values of all the options
            # we just told it about
            self.p.set_defaults(
                debug_level     = 0,          
                verbose_level   = 0,
                configfile_name = None,
                use_proc        = False,
                )       
            
        def parse(self):
            self.options, self.args = self.p.parse_args()
            self.debug_level     = self.options.debug_level    
            self.verbose_level   = self.options.verbose_level  
            self.configfileName  = self.options.configfile_name
            self.use_proc        = self.options.use_proc
            
            # Check to see if input or output file names have been
            # specified. If so, then try to open them, and if that is
            # successful, replace the default configfile and outfile file
            # descriptors.
            if self.configfileName:
                try:
                    tmpf = open(self.configfileName, 'r')
                    self.configfile = tmpf
                except IOError, earg:
                    print "Error opening Input file: -i %s" % (self.configfileName)
                    print "Expection argument:", earg
                    sys.exit()
            
            # Output option details if debugging level is high enough
            if self.debug_level >= 3 :
                print
                print "Options: ", self.options
                print "Args: ", self.args

        # Defining this method defines the string representation of the
        # object when given as an argument to str() or the "print" command
        def __str__(self):
            param_print_str = \
"""Parameters:
  debug_level    : %d
  verbose_level  : %d
  config_file    : %s
  output_file    : %s
  use_proc       : %s
""" 

            str_output = param_print_str % \
                (self.debug_level, 
                 self.verbose_level,
                 self.configfileName,
                 self.use_proc)            
            return str_output
        
    def main():
        # Global level params class instance was
        # created before calling main(). We make it
        # global so that other code can access the set
        # of Parameters, simply by accessing the Params
        # instance. Here, however, we call the parse()
        # method to actually get the arguments, since
        # we have been called from the command line.
        Params.parse()
        debug_level = Params.debug_level
        if Params.debug_level >= 2:
            print Params
    
    
        if Params.configfileName:
            gshConfig = parse_configfile(Params.configfileName)
            gsh = GSHierarchy(gshConfig)
            print gsh
        
        if Params.use_proc:
            gsh = gsproc.parse()
            print gsh
        
        
    
    global Params
    Params = Params_Set()

    main()
