#!/usr/bin/python2

# Copyright (c) 2015 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.

"""Method to add or modify ATTRIBUTES in the test control files whose
ATTRIBUTES either not match to SUITE or not in the attribute allowlist."""

import argparse
import logging
import os
import sys

import common
from autotest_lib.client.common_lib import control_data
from autotest_lib.server.cros.dynamic_suite.suite import Suite


def main(argv):
    """main scripts to seed attributes in test control files.

  Args:
    @param argv: Command line arguments including `sys.argv[0]`.
  """
    # Parse execution cmd
    parser = argparse.ArgumentParser(
            description='Seed ATTRIBUTES in test control files.')
    parser.add_argument('--execute',
                        action='store_true',
                        default=False,
                        help='Execute the script to seed attributes in all '
                        'test control files.')
    args = parser.parse_args(argv)

    # When execute is True, run the script to seed attributes in control files.
    if args.execute:
        # Get the allowlist path, hardcode the path currently
        path_allowlist = os.path.join(common.autotest_dir,
                                      'site_utils/attribute_allowlist.txt')

        # Go through all control file, check whether attribute matches suite. Return
        # a changelist which contains the paths to the control files not match.
        fs_getter = Suite.create_fs_getter(common.autotest_dir)
        changelist = AttrSuiteMatch(fs_getter.get_control_file_list(),
                                    path_allowlist)
        count = len(changelist)

        logging.info('Starting to seed attributes in %d control files...',
                     count)
        # Modify attributes based on suite for the control files not match.
        for path in changelist:
            logging.info('Seeding ATTRIBUTES in %s', path)
            count = count - 1
            logging.info('%d files remaining...', count)
            SeedAttributes(path)

        logging.info('Finished seeding attributes.')

    # When not specify 'execute' in cmd, not modify control files.
    else:
        logging.info(
                'No files are modified. To seed attributes in control files, '
                'please add \'--execute\' argument when run the script.')


def AttrSuiteMatch(path_list, path_allowlist):
    """Check whether attributes are in the attribute allowlist and match with the
  suites in the control files.

  Args:
    @param path_list: a list of path to the control files to be checked.
    @param path_allowlist: path to the attribute allowlist.

  Returns:
    A list of paths to the control files that failed at checking.
  """
    unmatch_pathlist = []

    # Read the allowlist to a set, if path is invalid, throw IOError.
    with open(path_allowlist, 'r') as f:
        allowlist = {line.strip() for line in f.readlines() if line.strip()}

    # Read the attr in the control files, check with allowlist and suite.
    for path in path_list:
        cd = control_data.parse_control(path, True)
        cd_attrs = cd.attributes

        # Test whether attributes in the allowlist
        if not (allowlist >= cd_attrs):
            unmatch_pathlist.append(path)
        # Test when suite exists, whether attributes match suites
        if hasattr(cd, 'suite'):
            target_attrs = set('suite:' + x.strip()
                               for x in cd.suite.split(',') if x.strip())
            if cd_attrs != target_attrs:
                unmatch_pathlist.append(path)
        # Test when suite not exists, whether attributes is empty
        elif not hasattr(cd, 'suite') and cd_attrs:
            unmatch_pathlist.append(path)

    return unmatch_pathlist


def SeedAttributes(path_controlfile):
    """Seed attributes in a control file.

  Read and re-write a control file with modified contents with attributes added.

  Args:
    @param path_controlfile: path to control file

  Returns:
    None
  """
    # Parse attribute from suite, and prepare ATTRIBUTES line.
    cd = control_data.parse_control(path_controlfile, True)
    suite = cd.suite

    attr_items = set('suite:' + x.strip() for x in suite.split(',')
                     if x.strip())
    attr_items = list(attr_items)
    attr_items.sort(key=str.lower)
    attr_line = ', '.join(attr_items)
    attr_line = 'ATTRIBUTES = \"' + attr_line + '\"\n'

    # Read control file and modify the suite line with attribute added.
    with open(path_controlfile, 'r') as f:
        lines = f.readlines()
        index = [
                i for i, val in enumerate(lines)
                if val.startswith('SUITE =') or val.startswith('SUITE=')
        ][0]
        suite_line = lines[index]
        lines[index] = attr_line + suite_line

    # Write the modified contents back to file
    with open(path_controlfile, 'w') as f:
        f.writelines(lines)


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
