#!/usr/bin/python3
# Copyright (c) 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.
"""Generate metadata for build from Autotest ctrl files."""

import argparse
import os
import six
import sys

# If running in Autotest dir, keep this.
os.environ["PY_VERSION"] = '3'

import common

# NOTE: this MUST be run in Python3, if we get configured back to PY2, exit.
if six.PY2:
    exit(1)

from autotest_lib.server.cros.dynamic_suite import control_file_getter
from autotest_lib.client.common_lib import control_data

from chromiumos.test.api import test_case_metadata_pb2 as tc_metadata_pb
from chromiumos.test.api import test_harness_pb2 as th_pb
from chromiumos.test.api import test_case_pb2 as tc_pb

HARNESS = th_pb.TestHarness.Tauto()


def parse_local_arguments(args):
    """Parse the CLI."""
    parser = argparse.ArgumentParser(
            description="Prep Autotest, Tast, & Services for DockerBuild.")
    parser.add_argument('-autotest_path',
                        dest='autotest_path',
                        default='../../../../third_party/autotest/files/',
                        help='path to autotest/files relative to this script.')
    parser.add_argument('-output_file',
                        dest='output_file',
                        default=None,
                        help='Where to write the serialized pb.')
    return parser.parse_args(args)


def read_file(filename):
    """Read the given file."""
    with open(filename, 'r') as f:
        return f.read()


def all_control_files(args):
    """Return all control files as control file objs."""
    subpaths = ['server/site_tests', 'client/site_tests']
    start_cwd = os.getcwd()
    try:
        os.chdir(args.autotest_path)

        # Might not be needed, but this resolves out the ../
        autotest_path = os.getcwd()

        directories = [os.path.join(autotest_path, p) for p in subpaths]
        f = control_file_getter.FileSystemGetter(directories)
    except Exception as e:
        raise Exception("Failed to find control files at path %s",
                        args.autotest_path)

    finally:
        os.chdir(start_cwd)
    return f._get_control_file_list()


def serialize_test_case_info(data):
    """Return a serialized TestCaseInfo obj."""
    serialized_contacts = tc_metadata_pb.Contact(email=data.author)
    return tc_metadata_pb.TestCaseInfo(owners=[serialized_contacts])


def serialize_tags(data):
    """Return a serialized tags obj (list)."""
    serialized_tags = []
    for value in data.dependencies:
        serialized_tags.append(tc_pb.TestCase.Tag(value=value))
    for value in data.attributes:
        serialized_tags.append(tc_pb.TestCase.Tag(value=value))
    if data.test_class:
        serialized_tags.append(
                tc_pb.TestCase.Tag(
                        value="test_class:{}".format(data.test_class)))
    return serialized_tags


def serialize_test_case(data):
    """Return a serialized api.TestCase obj."""
    serialized_testcase_id = tc_pb.TestCase.Id(value="tauto." + data.name)
    tags = serialize_tags(data)
    return tc_pb.TestCase(id=serialized_testcase_id, name=data.name, tags=tags)


def serialized_test_case_exec(data):
    """Return a serialized TestCaseExec obj."""
    serialized_test_harness = th_pb.TestHarness(tauto=HARNESS)
    return tc_metadata_pb.TestCaseExec(test_harness=serialized_test_harness)


def serialized_test_case_metadata(data):
    """Return a TestCaseMetadata obj from a given control file."""
    serialized_meta_data = tc_metadata_pb.TestCaseMetadata(
            test_case_exec=serialized_test_case_exec(data),
            test_case=serialize_test_case(data),
            test_case_info=serialize_test_case_info(data))
    return serialized_meta_data


def serialized_test_case_metadata_list(data):
    """Return a TestCaseMetadataList obj from a list of TestCaseMetadata pb."""
    serialized_meta_data_list = tc_metadata_pb.TestCaseMetadataList(
            values=data)
    return serialized_meta_data_list


def skip_control(data):
    """If the test has no attribute(suite), it should not be exported."""
    for item in data.attributes:
        if 'suite:' in item:
            return False
    return True


def main():
    """Generate the metadata, and if an output path is given, save it."""
    args = parse_local_arguments(sys.argv[1:])
    ctrlfiles = all_control_files(args)
    serialized_metadata = []
    for file_path in ctrlfiles:
        text = read_file(file_path)
        path = ctrlfiles[1]

        test = control_data.parse_control_string(text,
                                                 raise_warnings=True,
                                                 path=path)
        if skip_control(test):
            continue

        serialized_metadata.append(serialized_test_case_metadata(test))

    serialized = serialized_test_case_metadata_list(serialized_metadata)
    if args.output_file:
        with open(args.output_file, 'wb') as wf:
            wf.write(serialized.SerializeToString())


if __name__ == '__main__':
    main()
