#!/usr/bin/python2 -u
# Copyright (c) 2013 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.

"""
Check an autotest control file for required variables.

This wrapper is invoked through autotest's PRESUBMIT.cfg for every commit
that edits a control file.
"""


import argparse
import fnmatch
import glob
import os
import re
import subprocess

import common
from autotest_lib.client.common_lib import control_data
from autotest_lib.server.cros.dynamic_suite import reporting_utils


DEPENDENCY_ARC = 'arc'
SUITES_NEED_RETRY = set(['bvt-arc', 'bvt-cq', 'bvt-inline'])
TESTS_NEED_ARC = 'cheets_'
BVT_ATTRS = set(
    ['suite:smoke', 'suite:bvt-inline', 'suite:bvt-cq', 'suite:bvt-arc'])
TAST_PSA_URL = (
    'https://groups.google.com/a/chromium.org/d/topic/chromium-os-dev'
    '/zH1nO7OjJ2M/discussion')


class ControlFileCheckerError(Exception):
    """Raised when a necessary condition of this checker isn't satisfied."""


def IsInChroot():
    """Return boolean indicating if we are running in the chroot."""
    return os.path.exists("/etc/debian_chroot")


def CommandPrefix():
    """Return an argv list which must appear at the start of shell commands."""
    if IsInChroot():
        return []
    else:
        return ['cros_sdk', '--']


def GetOverlayPath(overlay=None):
    """
    Return the path to the overlay directory.

    If the overlay path is not given, the default chromiumos-overlay path
    will be returned instead.

    @param overlay: The overlay repository path for autotest ebuilds.

    @return normalized absolutized path of the overlay repository.
    """
    if not overlay:
        ourpath = os.path.abspath(__file__)
        overlay = os.path.join(os.path.dirname(ourpath),
                               "../../../../chromiumos-overlay/")
    return os.path.normpath(overlay)


def GetAutotestTestPackages(overlay=None):
    """
    Return a list of ebuilds which should be checked for test existance.

    @param overlay: The overlay repository path for autotest ebuilds.

    @return autotest packages in overlay repository.
    """
    overlay = GetOverlayPath(overlay)
    packages = glob.glob(os.path.join(overlay, "chromeos-base/autotest-*"))
    # Return the packages list with the leading overlay path removed.
    return [x[(len(overlay) + 1):] for x in packages]


def GetEqueryWrappers():
    """Return a list of all the equery variants that should be consulted."""
    # Note that we can't just glob.glob('/usr/local/bin/equery-*'), because
    # we might be running outside the chroot.
    pattern = '/usr/local/bin/equery-*'
    cmd = CommandPrefix() + ['sh', '-c', 'echo %s' % pattern]
    wrappers = subprocess.check_output(cmd).split()
    # If there was no match, we get the literal pattern string echoed back.
    if wrappers and wrappers[0] == pattern:
        wrappers = []
    return ['equery'] + wrappers


def GetUseFlags(overlay=None):
    """Get the set of all use flags from autotest packages.

    @param overlay: The overlay repository path for autotest ebuilds.

    @returns: useflags
    """
    useflags = set()
    for equery in GetEqueryWrappers():
        cmd_args = (CommandPrefix() + [equery, '-qC', 'uses'] +
                    GetAutotestTestPackages(overlay))
        child = subprocess.Popen(cmd_args, stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
        new_useflags = child.communicate()[0].splitlines()
        if child.returncode == 0:
            useflags = useflags.union(new_useflags)
    return useflags


def CheckSuites(ctrl_data, test_name, useflags):
    """
    Check that any test in a SUITE is also in an ebuild.

    Throws a ControlFileCheckerError if a test within a SUITE
    does not appear in an ebuild. For purposes of this check,
    the psuedo-suite "manual" does not require a test to be
    in an ebuild.

    @param ctrl_data: The control_data object for a test.
    @param test_name: A string with the name of the test.
    @param useflags: Set of all use flags from autotest packages.

    @returns: None
    """
    if (hasattr(ctrl_data, 'suite') and ctrl_data.suite and
        ctrl_data.suite != 'manual'):
        # To handle the case where a developer has cros_workon'd
        # e.g. autotest-tests on one particular board, and has the
        # test listed only in the -9999 ebuild, we have to query all
        # the equery-* board-wrappers until we find one. We ALSO have
        # to check plain 'equery', to handle the case where e.g. a
        # developer who has never run setup_board, and has no
        # wrappers, is making a quick edit to some existing control
        # file already enabled in the stable ebuild.
        for flag in useflags:
            if flag.startswith('-') or flag.startswith('+'):
                flag = flag[1:]
            if flag == 'tests_%s' % test_name:
                return
        raise ControlFileCheckerError(
                'No ebuild entry for %s. To fix, please do the following: 1. '
                'Add your new test to one of the ebuilds referenced by '
                'autotest-all. 2. cros_workon --board=<board> start '
                '<your_ebuild>. 3. emerge-<board> <your_ebuild>' % test_name)


def CheckValidAttr(ctrl_data, attr_whitelist, bvt_whitelist, test_name):
    """
    Check whether ATTRIBUTES are in the whitelist.

    Throw a ControlFileCheckerError if tags in ATTRIBUTES don't exist in the
    whitelist.

    @param ctrl_data: The control_data object for a test.
    @param attr_whitelist: whitelist set parsed from the attribute_whitelist.
    @param bvt_whitelist: whitelist set parsed from the bvt_whitelist.
    @param test_name: A string with the name of the test.

    @returns: None
    """
    if not (attr_whitelist >= ctrl_data.attributes):
        attribute_diff = ctrl_data.attributes - attr_whitelist
        raise ControlFileCheckerError(
            'Attribute(s): %s not in the whitelist in control file for test '
            'named %s. If this is a new attribute, please add it into '
            'AUTOTEST_DIR/site_utils/attribute_whitelist.txt file'
            % (attribute_diff, test_name))
    if ctrl_data.attributes & BVT_ATTRS:
        for pattern in bvt_whitelist:
            if fnmatch.fnmatch(test_name, pattern):
                break
        else:
            raise ControlFileCheckerError(
                '%s not in the BVT whitelist. New BVT tests should be written '
                'in Tast, not in Autotest. See: %s'
                % (test_name, TAST_PSA_URL))


def CheckSuiteLineRemoved(ctrl_file_path):
    """
    Check whether the SUITE line has been removed since it is obsolete.

    @param ctrl_file_path: The path to the control file.

    @raises: ControlFileCheckerError if check fails.
    """
    with open(ctrl_file_path, 'r') as f:
        for line in f.readlines():
            if line.startswith('SUITE'):
                raise ControlFileCheckerError(
                    'SUITE is an obsolete variable, please remove it from %s. '
                    'Instead, add suite:<your_suite> to the ATTRIBUTES field.'
                    % ctrl_file_path)


def CheckRetry(ctrl_data, test_name):
    """
    Check that any test in SUITES_NEED_RETRY has turned on retry.

    @param ctrl_data: The control_data object for a test.
    @param test_name: A string with the name of the test.

    @raises: ControlFileCheckerError if check fails.
    """
    if hasattr(ctrl_data, 'suite') and ctrl_data.suite:
        suites = set(x.strip() for x in ctrl_data.suite.split(',') if x.strip())
        if ctrl_data.job_retries < 2 and SUITES_NEED_RETRY.intersection(suites):
            raise ControlFileCheckerError(
                'Setting JOB_RETRIES to 2 or greater for test in '
                '%s is recommended. Please set it in the control '
                'file for %s.' % (' or '.join(SUITES_NEED_RETRY), test_name))


def CheckDependencies(ctrl_data, test_name):
    """
    Check if any dependencies of a test is required

    @param ctrl_data: The control_data object for a test.
    @param test_name: A string with the name of the test.

    @raises: ControlFileCheckerError if check fails.
    """
    if test_name.startswith(TESTS_NEED_ARC):
        if not DEPENDENCY_ARC in ctrl_data.dependencies:
            raise ControlFileCheckerError(
                    'DEPENDENCIES = \'arc\' for %s is needed' % test_name)


def main():
    """
    Checks if all control files that are a part of this commit conform to the
    ChromeOS autotest guidelines.
    """
    parser = argparse.ArgumentParser(description='Process overlay arguments.')
    parser.add_argument('--overlay', default=None, help='the overlay directory path')
    args = parser.parse_args()
    file_list = os.environ.get('PRESUBMIT_FILES')
    if file_list is None:
        raise ControlFileCheckerError('Expected a list of presubmit files in '
            'the PRESUBMIT_FILES environment variable.')

    # Parse the whitelist set from file, hardcode the filepath to the whitelist.
    path_attr_whitelist = os.path.join(common.autotest_dir,
                                       'site_utils/attribute_whitelist.txt')
    with open(path_attr_whitelist, 'r') as f:
        attr_whitelist = {
            line.strip() for line in f.readlines() if line.strip()}

    path_bvt_whitelist = os.path.join(common.autotest_dir,
                                      'site_utils/bvt_whitelist.txt')
    with open(path_bvt_whitelist, 'r') as f:
        bvt_whitelist = {line.strip() for line in f.readlines() if line.strip()}

    # Delay getting the useflags. The call takes long time, so init useflags
    # only when needed, i.e., the script needs to check any control file.
    useflags = None
    for file_path in file_list.split('\n'):
        control_file = re.search(r'.*/control(?:\..+)?$', file_path)
        if control_file:
            ctrl_file_path = control_file.group(0)
            CheckSuiteLineRemoved(ctrl_file_path)
            ctrl_data = control_data.parse_control(ctrl_file_path,
                                                   raise_warnings=True)
            test_name = os.path.basename(os.path.split(file_path)[0])
            try:
                reporting_utils.BugTemplate.validate_bug_template(
                        ctrl_data.bug_template)
            except AttributeError:
                # The control file may not have bug template defined.
                pass

            if not useflags:
                useflags = GetUseFlags(args.overlay)
            CheckSuites(ctrl_data, test_name, useflags)
            CheckValidAttr(ctrl_data, attr_whitelist, bvt_whitelist, test_name)
            CheckRetry(ctrl_data, test_name)
            CheckDependencies(ctrl_data, test_name)


if __name__ == '__main__':
    main()
