#!/usr/bin/env python

"""Command-line interface."""

import sys
import argparse

from . import CLI, VERSION, DESCRIPTION
from . import common
from . import commands

log = common.logger(__name__)


def main(args=None, function=None):
    """Process command-line arguments and run the program."""

    # Shared options
    debug = argparse.ArgumentParser(add_help=False)
    debug.add_argument('-V', '--version', action='version', version=VERSION)
    group = debug.add_mutually_exclusive_group()
    group.add_argument('-v', '--verbose', action='count', default=0,
                       help="enable verbose logging")
    group.add_argument('-q', '--quiet', action='store_const', const=-1,
                       dest='verbose', help="only display errors and prompts")
    project = argparse.ArgumentParser(add_help=False)
    project.add_argument('-r', '--root', metavar='PATH',
                         help="root directory of the project")
    shared = {'formatter_class': common.WideHelpFormatter,
              'parents': [project, debug]}

    # Main parser
    parser = argparse.ArgumentParser(prog=CLI, description=DESCRIPTION,
                                     **shared)

    subs = parser.add_subparsers(help="", dest='command', metavar="<command>")

    # Install parser
    info = "get the specified versions of all dependencies"
    sub = subs.add_parser('install', description=info.capitalize() + '.',
                          help=info, **shared)
    sub.add_argument('-f', '--force', action='store_true',
                     help="overwrite uncommitted changes in dependencies")
    sub.add_argument('-C', '--no-clean', action='store_false', dest='clean',
                     help="keep ignored files in dependencies")

    # Update parser
    info = "update all dependencies to the latest versions"
    sub = subs.add_parser('update', description=info.capitalize() + '.',
                          help=info, **shared)
    # TODO: share these with 'install'
    sub.add_argument('-f', '--force', action='store_true',
                     help="overwrite uncommitted changes in dependencies")
    sub.add_argument('-C', '--no-clean', action='store_false', dest='clean',
                     help="keep ignored files in dependencies")

    # Display parser
    info = "display the current version of each dependency"
    sub = subs.add_parser('list', description=info.capitalize() + '.',
                          help=info, **shared)
    sub.add_argument('-D', '--no-dirty', action='store_false',
                     help="fail if a source has uncommitted changes")

    # Uninstall parser
    info = "delete all installed dependencies"
    sub = subs.add_parser('uninstall', description=info.capitalize() + '.',
                          help=info, **shared)
    sub.add_argument('-f', '--force', action='store_true',
                     help="delete uncommitted changes in dependencies")

    # Parse arguments
    args = parser.parse_args(args=args)
    kwargs = dict(root=args.root)
    retry_msg = ""
    if args.command in ('install', 'update'):
        function = getattr(commands, args.command)
        kwargs.update(dict(force=args.force,
                           clean=args.clean))
        retry_msg = "\n" + "Run again with '--force' to overwrite"
    elif args.command == 'uninstall':
        function = commands.delete
        kwargs.update(dict(force=args.force))
        retry_msg = "\n" + "Run again with '--force' to ignore"
    elif args.command == 'list':
        function = commands.display
        kwargs.update(dict(allow_dirty=args.no_dirty))
    if function is None:
        parser.print_help()
        sys.exit(1)

    # Configure logging
    common.configure_logging(args.verbose)

    # Run the program
    success = False
    exit_msg = ""
    try:
        log.debug("running command...")
        success = function(**kwargs)
    except KeyboardInterrupt:
        msg = "command canceled"
        if common.verbosity == common.MAX_VERBOSITY:
            log.exception(msg)
        else:
            log.debug(msg)
    except RuntimeError as exc:
        exit_msg = str(exc) + retry_msg
    if success:
        log.debug("command succeeded")
    else:
        log.debug("command failed")
        sys.exit(exit_msg or 1)


if __name__ == '__main__':  # pragma: no cover (manual test)
    main()

@@ -3006,29 +3006,28 @@
 s.root)%0A    
-retry
+exit
 _msg = %22%22%0A  
@@ -3212,37 +3212,36 @@
 clean))%0A        
-retry
+exit
 _msg = %22%5Cn%22 + %22R
@@ -3405,21 +3405,20 @@
         
-retry
+exit
 _msg = %22
@@ -3768,34 +3768,16 @@
 = False%0A
-    exit_msg = %22%22%0A
     try:
@@ -4108,17 +4108,48 @@
 ) + 
-retry_msg
+exit_msg%0A    else:%0A        exit_msg = %22%22
 %0A   

Refactor exit message into a single variable