#!python
# -*- coding: utf-8 -*-

import argparse
import logging
import os
import sys
from builtins import AttributeError, Exception

from python_env import create_env

PYTHON_VERSION = 'python{}'.format(sys.version_info.major)


def _add_commands(parser):
    commands = parser.add_subparsers(title='Available Commands', help='command help')

    # crawl command
    crawl_command = commands.add_parser('setup', help='Setup your projects virtual env')
    crawl_command.set_defaults(main=create_env.main)


def _add_global_options(parser):
    global_options = parser.add_argument_group("Global Options")
    verbosity_group = global_options.add_mutually_exclusive_group()
    verbosity_group.add_argument(
        '-q', '--quiet',
        dest='verbosity',
        action='store_const',
        const=0,
        default=1,
        help='Only show errors.'
    )
    verbosity_group.add_argument(
        '-v', '--verbose',
        dest='verbosity',
        action='count',
        help='Increase verbosity. -v for INFO and -vv for DEBUG. Default: WARNING'
    )

    global_options.add_argument('-d', '--dir',
                                metavar='DIR',
                                default=os.environ.get('VIRTUAL_ENV_DIR', '.venv'),
                                help='The desired directory name for your virtual env.  Default: "%(default)s"')

    global_options.add_argument('-p', '--python',
                                metavar='PYTHON_EXE',
                                default=PYTHON_VERSION,
                                help="""
                                The Python interpreter to use, e.g.,
                                --python=python3.5 will use the python3.5 interpreter
                                to create the new environment.  The default is the
                                interpreter that this tool is running with ({})
                                """.format(PYTHON_VERSION))

    global_options.add_argument('-ni', '--non-interactive',
                                action='store_true',
                                help='Non-interactive mode.  Will silently use all defaults.  Default: False')


def _run_command(parser, logger, args):
    try:
        # noinspection PyProtectedMember
        returncode = args.main(args)
    except AttributeError as e:
        parser.print_help()
        return 1
    except Exception as e:
        logger.error('{}: {}'.format(e.__class__.__name__, str(e)))
        returncode = 2

    return returncode if returncode else 0


def main(argv=None):
    argv = argv or sys.argv[1:]
    parser = argparse.ArgumentParser()
    _add_global_options(parser)
    _add_commands(parser)

    # Parse input
    args = parser.parse_args(args=argv)

    # Setup logging
    logger = logging.getLogger()

    assert args.verbosity >= 0, 'verbosity seems to be non-positive'
    levels = [
        logging.ERROR,
        logging.WARNING,
        logging.INFO,
        logging.DEBUG,
    ]

    level = logging.NOTSET
    if args.verbosity < len(levels):
        level = levels[args.verbosity]

    _format = "%(asctime)s.%(msecs)03d [%(process)d]: %(name)s %(levelname)s: %(message)s"
    logging.basicConfig(format=_format, level=level, datefmt='%Y-%m-%d %H:%M:%S', stream=sys.stderr)

    # Execute the command
    return _run_command(parser, logger, args)


if __name__ == '__main__':
    sys.exit(main())
