from phaser import tbx_utils

try:
  import argparse
  
except ImportError:
  from libtbx.utils import Sorry
  raise Sorry, "The argparse module is not available. Check Python version >= 2.7"
        

class PhilPrintAction(argparse.Action):
    """
    Action to print phil
    """
    
    def __init__(
        self,
        option_strings,
        dest = argparse.SUPPRESS,
        default = argparse.SUPPRESS,
        help = None
        ):
    
        super( PhilPrintAction, self ).__init__(
            option_strings = option_strings,
            dest = dest,
            default = default,
            nargs = 0,
            help = help,
            )

    def __call__(self, parser, namespace, values, option_string = None):
        
        parser.print_phil()
        parser.exit()
        
        
#class PhilArgumentAction(argparse._Append):
        

class CaptureStdinPhilAction(argparse.Action):
    """
    Action to capture stdin
    """
    
    def __init__(self, option_strings, dest, default = argparse.SUPPRESS, help = None):
    
        super( CaptureStdinPhilAction, self ).__init__(
            option_strings = option_strings,
            dest = dest,
            default = default,
            nargs = 0,
            help = help,
            )
        
    
    def __call__(self, parser, namespace, values, option_string = None):
        
        import sys
        
        try:
            value = tbx_utils.PhilArgument.from_string( string = sys.stdin.read() )
            
        except ValueError, e:
            parser.error( "Error while reading from stdin: %s\n" % e )
            
        setattr( namespace, self.dest, value )
        

class PCLIParser(argparse.ArgumentParser):
    """
    Extended parser that handles help and phil
    """
    
    def __init__(self, master_phil, *args, **kwargs):
        
        super( PCLIParser, self ).__init__( *args, **kwargs )
        self.master_phil = master_phil
        
        self.add_argument(
            "phils",
            nargs = "*",
            metavar = "PHIL",
            action = "store",
            default = [],
            type = tbx_utils.PhilArgumentFactory( master_phil = master_phil ),
            help = "PHIL argument (file name or PHIL command line assignment)"
            )
        
        default_prefix = '-' if '-' in self.prefix_chars else self.prefix_chars[0]
        self.add_argument(
            default_prefix * 2 + "show-defaults",
            action = PhilPrintAction,
            help= "print PHIL and exit",
            )
        self.add_argument(
            default_prefix + "i", default_prefix * 2 + "stdin",
            action = CaptureStdinPhilAction,
            help= "read PHIL from stdin as well",
            )
        
        
    def print_help(self, file = None):
        
        if file is None:
            file = argparse._sys.stdout
            
        super( PCLIParser, self )._print_message( self.format_help(), file )
        super( PCLIParser, self )._print_message( "\nPHIL definition:\n", file )
        super( PCLIParser, self )._print_message(
            self.master_phil.as_str() + "\n",
            file,
            )
        
        
    def print_phil(self, file = None):
        
        if file is None:
            file = argparse._sys.stdout
            
        super( PCLIParser, self )._print_message(
            self.master_phil.as_str() + "\n",
            file,
            )
        
    
    def parse_args(self, args = None, namespace = None):
        
        args = super( PCLIParser, self ).parse_args(
            args = args,
            namespace = namespace
            )
        
        if hasattr( args, "stdin" ):
            args.phils.append( args.stdin )
            delattr( args, "stdin" )
        
        return args

