# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import getpass
import logging
import sys

import common
from autotest_lib.client.common_lib import utils


def setup_logging(log_level):
    """Sets up direct logging to stdout for unittests.

    @param log_level: Level of logging to redirect to stdout, default to INFO.
    """
    # Lifted from client.common_lib.logging_config.
    FORMAT = ('%(asctime)s.%(msecs)03d %(levelname)-5.5s|%(module)18.18s:'
              '%(lineno)4.4d| %(threadName)16.16s(%(thread)d)| %(message)s')

    logger = logging.getLogger()
    logger.setLevel(log_level)
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(log_level)
    formatter = logging.Formatter(FORMAT)
    handler.setFormatter(formatter)
    logger.handlers = []
    logger.addHandler(handler)


def verify_user(require_sudo=True):
    """Checks that the current user is not root, but has sudo.

    Running unit tests as root can mask permissions problems, as not all the
    code runs as root in production.
    """
    # Ensure this process is not running as root.
    if getpass.getuser() == 'root':
        raise EnvironmentError('Unittests should not be run as root.')

    # However, most of the unit tests do require sudo.
    # TODO(dshi): crbug.com/459344 Set remove this enforcement when test
    # container can be unprivileged container.
    if require_sudo and utils.sudo_require_password():
        logging.warn('SSP requires root privilege to run commands, please '
                     'grant root access to this process.')
        utils.run('sudo true')


class Config(object):
    """A class for parsing and storing command line options.

    A convenience class for helping with unit test setup.  A global instance of
    this class is set up by the setup function.  Clients can then check this
    object for flags set on the command line.
    """
    def parse_options(self):
        """Parses command line flags for unittests."""
        parser = argparse.ArgumentParser()
        parser.add_argument('-v', '--verbose', action='store_true',
                            default=False,
                            help='Print out ALL entries.')
        parser.add_argument('-s', '--skip_cleanup', action='store_true',
                            default=False,
                            help='Skip deleting test containers.')
        args, argv = parser.parse_known_args()

        for attr, value in vars(args).items():
            setattr(self, attr, value)

        # Hack: python unittest also processes args.  Construct an argv to pass
        # to it, that filters out the options it won't recognize.  Then replace
        # sys.argv with the constructed argv so that calling unittest.main "just
        # works".
        if args.verbose:
            argv.insert(0, '-v')
        argv.insert(0, sys.argv[0])
        sys.argv = argv


# Global namespace object for storing unittest options specified on the command
# line.
config = Config()

def setup(require_sudo=True):
    """Performs global setup for unit-tests."""
    global setup_run
    config.parse_options()

    verify_user(require_sudo)

    log_level = logging.DEBUG if config.verbose else logging.INFO
    setup_logging(log_level)
