#!/usr/bin/python
#
# Licensed under the GNU General Public License Version 3
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright 2010 Aron Parsons <aron@redhat.com>
#

""" spacecmd - a command line interface to Spacewalk """

import logging, os, re, sys, xmlrpclib
from ConfigParser import SafeConfigParser, NoOptionError
from optparse import Option, OptionParser
from spacecmd.shell import SpacewalkShell
    
_INTRO = '''Welcome to spacecmd, a command-line interface to Spacewalk.

Type: 'help' for a list of commands
      'help <cmd>' for command-specific help
      'quit' to quit
'''

_SYSTEM_CONF_FILE = '/etc/spacecmd.conf'

if __name__ == '__main__':
    optionsTable = [
        Option('-u', '--username', action='store',
               help='use this username to connect to the server'),
        Option('-p', '--password', action='store',
               help='use this password to connect to the server'),
        Option('-s', '--server', action='store',
               help='connect to this server [default: localhost]'),
        Option('--nossl', action='store_true',
               help='use HTTP instead of HTTPS'),
        Option('--nohistory', action='store_true',
                help='do not store command history'),
        Option('-y', '--yes', action='store_true',
               help='answer yes for all questions'),
        Option('-q', '--quiet', action='store_true',
               help='print only error messages'),
        Option('-d', '--debug', action='count',
               help='print debug messages (can be passed multiple times)'),
    ]

    usage = 'usage: %prog [options] [command]'

    parser = OptionParser(option_list=optionsTable, usage=usage)
    (options, args) = parser.parse_args()

    # determine the logging level
    if options.debug:
        level = logging.DEBUG
    elif options.quiet:
        level = logging.ERROR
    else:
        level = logging.INFO

    # configure logging
    logging.basicConfig(level=level, format='%(levelname)s: %(message)s')

    # files are loaded from ~/.spacecmd/
    conf_dir = os.path.expanduser('~/.spacecmd')
    user_conf_file = os.path.join(conf_dir, 'config')

    # server-specifics will be loaded from the configuration file later
    config = SafeConfigParser()

    # create an instance of the shell
    shell = SpacewalkShell(options, conf_dir, config)

    # set the default server to localhost
    if shell.options.server:
        shell.config['server'] = shell.options.server
    else:
        shell.config['server'] = 'localhost'

    # create an empty configuration file if one's not present
    if not os.path.isfile(user_conf_file):
        try:
            # create ~/.spacecmd
            if not os.path.isdir(conf_dir):
                logging.debug('Creating %s' % conf_dir)
                os.mkdir(conf_dir, 0700)
           
            # create a template configuration file 
            logging.debug('Creating configuration file: %s' % user_conf_file)
            handle = open(user_conf_file, 'w')
            handle.write('[spacecmd]\n')
            handle.close()
        except IOError:
            logging.error('Could not create %s' % user_conf_file)

    # load options from configuration files
    files_read = config.read( [ _SYSTEM_CONF_FILE, user_conf_file ] )

    for item in files_read:
        logging.debug('Read configuration from %s' % item)

    # load the default configuration section
    shell.load_config_section('spacecmd')

    # run a single command from the command line
    if len(args):
        try:
            # run the command
            shell.onecmd(shell.precmd(' '.join(args)))
        except KeyboardInterrupt:
            print
            print 'User Interrupt'
        except Exception, detail:
            # get the relevant part of a XML-RPC fault
            if isinstance(detail, xmlrpclib.Fault):
                detail = detail.faultString

            if shell.options.debug:
                # print the traceback when debugging
                logging.exception(detail)
            else:
                logging.error(detail)

            sys.exit(1)
    else:
        if not shell.options.quiet:
            print _INTRO

        if not shell.do_login(''):
            sys.exit(1)

        # stay in the interactive shell forever
        while True:
            try:
                shell.cmdloop()
            except KeyboardInterrupt:
                print
            except SystemExit:
                sys.exit(0)
            except Exception, detail:
                # get the relevant part of a XML-RPC fault
                if isinstance(detail, xmlrpclib.Fault):
                    detail = detail.faultString

                    # the session expired
                    if re.search('Could not find session', detail, re.I):
                        shell.session = ''

                if shell.options.debug:
                    # print the traceback when debugging
                    logging.exception(detail)
                else:
                    logging.error(detail)

# vim:ts=4:expandtab:
