#
# Copyright 2008 Google Inc. All Rights Reserved.
#
"""Command line interface for autotest

This module contains the generic CLI processing

See topic_common.py for a High Level Design and Algorithm.

This file figures out the topic and action from the 2 first arguments
on the command line and imports the site_<topic> or <topic> module.

It then creates a <topic>_<action> object, and calls it parses),
execute() and output() methods.
"""

__author__ = 'jmeurin@google.com (Jean-Marc Eurin)'

import os, sys, re, traceback

import common
from autotest_lib.cli import topic_common
from autotest_lib.server import utils


def main():
    """
    The generic syntax is:
    atest <topic> <action> <options>
    atest-<topic> <action> <options>
    atest --help
    """
    utils.verify_not_root_user()
    cli = os.path.basename(sys.argv[0])
    syntax_obj = topic_common.atest()

    # Normalize the various --help, -h and help to -h
    sys.argv = [re.sub('--help|help', '-h', arg) for arg in sys.argv]

    match = re.search('^atest-(\w+)$', cli)
    if match:
        topic = match.group(1)
    else:
        if len(sys.argv) > 1:
            topic = sys.argv.pop(1)
        else:
            syntax_obj.invalid_syntax('No topic argument')


    if topic == '-h':
        sys.argv.insert(1, '-h')
        syntax_obj.parse()

    # The ignore flag should *only* be used by unittests.
    ignore_site = '--ignore_site_file' in sys.argv
    if ignore_site:
        sys.argv.remove('--ignore_site_file')

    # Import the topic specific file
    cli_dir = os.path.abspath(os.path.dirname(__file__))
    if (not ignore_site and
        os.path.exists(os.path.join(cli_dir, 'site_%s.py' % topic))):
        topic = 'site_%s' % topic
    elif not os.path.exists(os.path.join(cli_dir, '%s.py' % topic)):
        syntax_obj.invalid_syntax('Invalid topic %s' % topic)
    topic_module = common.setup_modules.import_module(topic,
                                                      'autotest_lib.cli')

    # If we have a syntax error now, it should
    # refer to the topic class.
    topic_class = getattr(topic_module, topic)
    topic_obj = topic_class()

    if len(sys.argv) > 1:
        action = sys.argv.pop(1)

        if action == '-h':
            action = 'help'
            sys.argv.insert(1, '-h')
    else:
        topic_obj.invalid_syntax('No action argument')

    # Any backward compatibility changes?
    action = topic_obj.backward_compatibility(action, sys.argv)

    # Instantiate a topic object
    try:
        action_class = getattr(topic_module, topic + '_' + action)
    except AttributeError:
        topic_obj.invalid_syntax('Invalid action %s' % action)

    action_obj = action_class()

    action_obj.parse()
    try:
        try:
            results = action_obj.execute()
        except topic_common.CliError:
            pass
        except Exception, err:
            traceback.print_exc()
            action_obj.generic_error("Unexpected exception: %s" % err)
        else:
            try:
                action_obj.output(results)
            except Exception:
                traceback.print_exc()
    finally:
        return action_obj.show_all_failures()
