# Copyright 2021 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.
"""Script to generate Tauto test wrappers based on JSON configuration.

USAGE: python generate_tests.py <config_file.json>

This script generates control files for wrapping all Tast test files provided
in the configuration JSON file with a Tauto test cases. No Tauto suite files are
generated, these assumed to be added manually.

Configuration file may contain multiple suites, in which case, all tests of all
suites will be generated.

Configuration file is validated against the schema in config_schema.yaml file.
Schema file must be located in the same folder with the current script.
"""

import copy
import json
import os
import sys
from jsonschema import validate
import yaml

SCHEMA_FILE = 'config_schema.yaml'
TEST_TEMPLATE_FILE = 'template.control.performance_cuj'

# The priority of the first test. Decremented by 1 for each subsequent test.
INITIAL_PRIORITY = 5000

# Max duration of a single test.
HOUR_IN_SECS = 60 * 60
DEFAULT_TEST_DURATION = 1 * HOUR_IN_SECS


def _get_absolute_path(local_file):
    return os.path.join(os.path.dirname(os.path.realpath(__file__)),
                        local_file)


def _load_json_config(config_path):
    with open(_get_absolute_path(config_path), 'r') as config_file:
        return json.load(config_file)


def _validate_config_schema(json_config):
    # Loading the schema file
    with open(SCHEMA_FILE, 'r') as schema_file:
        schema = yaml.load(schema_file)

    validate(json_config, schema)


def _parse_constants(json_config):
    consts = dict()
    if 'const' in json_config:
        for c in json_config['const']:
            consts[c['name']] = c['value']
    return consts


def _substitute_constants(val, constants):
    for const in constants:
        val = val.replace('$' + const + '$', constants[const])
    return val


def _parse_tests(json_config, constants):
    tests = []
    for test in json_config['tests']:
        new_test = copy.deepcopy(test)
        # Substitute constants in all fields of the test.
        new_test['name'] = _substitute_constants(new_test['name'], constants)
        new_test['test_expr'] = _substitute_constants(new_test['test_expr'],
                                                      constants)
        if 'args' in new_test:
            new_args = []
            for arg in new_test['args']:
                new_args.append(_substitute_constants(arg, constants))
            new_test['args'] = new_args
        if 'attributes' in new_test:
            new_attrs = []
            for attr in new_test['attributes']:
                new_attrs.append(_substitute_constants(attr, constants))
            new_test['attributes'] = new_attrs
        tests.append(new_test)
    return tests


def _find_test(test_name, tests):
    for test in tests:
        if test['name'] == test_name:
            return test
    return None


def _parse_suites(json_config, tests, constants):
    suites = []
    for suite in json_config['suites']:
        new_suite = copy.deepcopy(suite)
        new_suite['name'] = _substitute_constants(new_suite['name'], constants)
        if 'args_file' in new_suite:
            new_suite['args_file'] = _substitute_constants(
                    new_suite['args_file'], constants)
        if 'args' in new_suite:
            new_args = []
            for arg in new_suite['args']:
                new_args.append(_substitute_constants(arg, constants))
            new_suite['args'] = new_args
        for test in new_suite['tests']:
            if not _find_test(test['test'], tests):
                raise Exception(
                        'Test %s (requested by suite %s) is not defined.' %
                        (test['test'], new_suite['name']))
            test['test'] = _substitute_constants(test['test'], constants)
        suites.append(new_suite)
    return suites


def _read_file(filename):
    with open(filename, 'r') as content_file:
        return content_file.read()


def _write_file(filename, data):
    with open(filename, 'w') as out_file:
        out_file.write(data)


def _normalize_test_name(test_name):
    return test_name.replace('.', '_').replace('*', '_')


def _calculate_suffix(current_index, repeats):
    # No suffix for single tests.
    if repeats == 1:
        return ''
    # Number of suffix digits depends on the total repeat count.
    digits = len(str(repeats))
    format_string = ('_{{index:0{digits}n}}').format(digits=digits)
    return format_string.format(index=current_index)


def _generate_test_files(version, suites, tests):
    template = _read_file(_get_absolute_path(TEST_TEMPLATE_FILE))
    priority = INITIAL_PRIORITY
    for suite in suites:
        for test in suite['tests']:
            test_data = _find_test(test['test'], tests)
            repeats = test['repeats']
            for i in range(repeats):
                test_name = _normalize_test_name(
                        test_data['test_expr'] +
                        _calculate_suffix(i + 1, repeats))
                control_file = template.format(
                        name=test_name,
                        priority=priority,
                        duration=DEFAULT_TEST_DURATION,
                        test_exprs=test_data['test_expr'],
                        length='long',
                        version=version,
                        attributes='suite:' + suite['name'],
                )
                control_file_name = 'control.' + '_'.join(
                        [suite['name'], test_name])
                _write_file(control_file_name, control_file)
                priority = priority - 1


def main(argv):
    """Main program that parses JSON configuration and generates test wrappers."""
    if not argv or len(argv) != 2:
        raise Exception(
                'Missing command-line arguments. Usage: python generate_tests.py <config_file.json>'
        )

    # Load and validate the config JSON file.
    json_config = _load_json_config(argv[1])
    _validate_config_schema(json_config)

    version = json_config['version']
    constants = _parse_constants(json_config)
    tests = _parse_tests(json_config, constants)
    suites = _parse_suites(json_config, tests, constants)
    _generate_test_files(version, suites, tests)


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