#!/usr/bin/env python3
#
import argparse
import importlib
import sys
from   os         import path

if __name__ == '__main__':
    sys.path.append( path.abspath( path.dirname( path.realpath(__file__))))

import palm


LOG = palm.logger(__name__)


__COMMANDS__ = {
    'build': 'palm.cmd.build',
    'run':   'palm.cmd.run',
    'test':  'palm.cmd.test'
    }


def main( prog=None, argv=None ):

    # palm-cli [-h]
    # palm-cli [-h] build [--pref <yamlfile>][<palmbuild-option>][--python]
    # palm-cli [-h] run [--pref <yamlfile>][<palmrun-option>]
    # palm-cli [-h] test self [<unittest-option>]
    # palm-cli [-h] test yaml <yamlfile> [<palmrun-option>]
    #
    result = 0

    try:
        opt, argv = parse_option( prog, argv )

        command = opt.get('command')
        if command is None:
            build_argparse(prog).print_help()

        elif opt.get('help') == True:
            result = get_module(command).main(
                'palm-cli '+ command,
                argv + ['-h']
                )

        else:
            result = get_module(command).main(
                'palm-cli '+ command,
                argv
                )

    except KeyboardInterrupt:
        LOG.info('')
        LOG.info('+++ palm-cli killed by "^C"')

        result = 2

    except Exception as exception:
        if palm.traceback:
            LOG.error( exception, exc_info=True )
        else:
            LOG.error( str(exception) )

        result = 1

    return result


def parse_option( prog=None, argv=None ):

    parser     = build_argparse( prog )
    opts, argv = parser.parse_known_args( argv )

    # FIXME: is there a better way to filter
    #        None-values from argparse.Namespace?
    #
    opts = dict( [ opt for opt in vars(opts).items() if not opt[1] is None ])
    if opts.get('traceback'):
        palm.traceback = True  # show traceback on error
        del opts['traceback']  # delete from options

    return opts, argv


def build_argparse( prog=None ):

    result = argparse.ArgumentParser(
        prog=prog,
        description='''PALM command line interface.''',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        add_help=False
        )
    result.add_argument(
        dest='command',
        metavar='<COMMAND>',
        choices=__COMMANDS__.keys(),
        action='store',
        nargs='?',
        help='command to execute'
        )
    result.add_argument(
        '-h', '--help',
        dest='help',
        action='store_true',
        help='show help, use \'-h '+('|'.join(__COMMANDS__.keys()))+'\' to read more about a specific command.'
        )
    result.add_argument(
        '--traceback',
        dest='traceback',
        action='store_true',
        default=None,
        help='Show traceback on error'
        )

    return result


def get_module( command ):

    package = __COMMANDS__.get(command)
    if package is None:
        package = 'palm.cmd.' + command

    result = importlib.import_module( package )

    return result


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