#!/usr/bin/env python3
# Copyright 2025 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import argparse
import logging
import os
import pprint
import sys
import tempfile
from typing import Dict, List, Optional, Tuple

# //testing/buildbot is only retrieved via DEPS for standalone checkouts.
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
DAWN_TESTING_BUILDBOT_DIR = os.path.realpath(
    os.path.join(THIS_DIR, '..', '..', 'testing', 'buildbot'))
if os.path.isdir(DAWN_TESTING_BUILDBOT_DIR):
    TESTING_BUILDBOT_DIR = DAWN_TESTING_BUILDBOT_DIR
else:
    raise RuntimeError(
        'Unable to find //testing/buildbot/ - it seems likely that you are '
        'running this from a Chromium checkout. Please run this from a '
        'standalone Dawn checkout.')

sys.path.insert(0, TESTING_BUILDBOT_DIR)
import generate_buildbot_json

# Add custom mixins here.
ADDITIONAL_MIXINS = {
    'no_swarming': {
        'swarming': {
            'can_use_on_swarming_builders': False,
        },
    },
    'result_adapter_gtest_json': {
        'resultdb': {
            'result_format': 'gtest_json',
        },
    },
}

MIXIN_FILEPATH = os.path.join(THIS_DIR, 'mixins.pyl')
MIXINS_PYL_TEMPLATE = """\
# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name} using data from {data_source}
#
# Copyright 2025 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This is a .pyl, or "Python Literal", file. You can treat it just like a
# .json file, with the following exceptions:
# * all keys must be quoted (use single quotes, please);
# * comments are allowed, using '#' syntax; and
# * trailing commas are allowed.
#
# For more info see Chromium's mixins.pyl in testing/buildbot.

{mixin_data}
"""


def _generate_mixins_pyl(
        generator: generate_buildbot_json.BBJSONGenerator) -> str:
    """Helper function to generate the mixins.pyl file.

    Args:
        generator: The BBJSONGenerator instance to use for generating mixins.

    Returns:
        A string containing the generated mixins.pyl content.
    """
    mixins = _get_trimmed_mixins(generator)
    pp = pprint.PrettyPrinter(indent=2)
    generated_mixin_pyl = MIXINS_PYL_TEMPLATE.format(
        script_name=os.path.basename(__file__),
        data_source="waterfalls.pyl and Chromium's mixins.pyl",
        mixin_data=pp.pformat(mixins))
    return generated_mixin_pyl


def _get_trimmed_mixins(
        generator: generate_buildbot_json.BBJSONGenerator) -> Dict[str, dict]:
    """Helper function to get a trimmed set of mixins.

    Chromium-provided mixins trimmed to only those that are actually used by
    Dawn, then merged with any Dawn-specific mixins.

    Args:
        generator: The BBJSONGenerator instance to use for generating mixins.

    Returns:
        The resulting dict mapping mixin name to mixin definition.
    """
    seen_mixins = set()
    for waterfall in generator.waterfalls:
        seen_mixins |= set(waterfall.get('mixins', []))
        for builder_spec in waterfall['machines'].values():
            seen_mixins |= set(builder_spec.get('mixins', []))
    for suite in generator.test_suites.values():
        if isinstance(suite, list):
            # This is a compound suite, which does not include any mixins.
            continue
        for test in suite.values():
            assert isinstance(test, dict)
            seen_mixins |= set(test.get('mixins', []))

    chromium_mixins = generator.load_pyl_file(
        os.path.join(TESTING_BUILDBOT_DIR, 'mixins.pyl'))
    kept_mixins = ADDITIONAL_MIXINS.copy()
    for mixin in seen_mixins:
        if mixin in kept_mixins:
            continue
        assert mixin in chromium_mixins, f'Mixin {mixin} used but not defined'
        kept_mixins[mixin] = chromium_mixins[mixin]

    return kept_mixins


def _write_or_verify_file(filepath: str, new_content: str,
                          verify_only: bool) -> None:
    """Helper function to either write content to disk or verify it matches.

    Args:
        filepath: The filepath to write |new_content| to if |verify_only| is
            False.
        new_content: The new content potentially being written to |filepath|.
        verify_only: Determines whether |new_content| is actually written to
            disk vs. asserting that the existing on-disk content matches
            |new_content|.
    """
    if verify_only:
        with open(filepath, encoding='utf-8') as infile:
            existing_content = infile.read()
        if existing_content != new_content:
            raise RuntimeError(
                f'Generated and existing content for {filepath} do not match. '
                f'Please run {__file__} to re-generate content.')
    else:
        with open(filepath, 'w', encoding='utf-8') as outfile:
            outfile.write(new_content)


def _run_generator(generator_args: List[str],
                   output_dir: Optional[str] = None) -> None:
    """Runs the generate_buildbot_json script for Dawn.

    Args:
        generator_args: A list of command line arguments to pass on to the
            generator.
        output_dir: An optional filepath to a directory to use for output. If
            set, it is assumed that the generator is being run to verify that
            generated files are up to date instead of actually saving updated
            files to disk.
    """
    verify_only = output_dir != None

    assert '--pyl-files-dir' not in generator_args
    generator_args.extend(['--pyl-files-dir', THIS_DIR])
    if verify_only:
        assert '--output-dir' not in generator_args
        generator_args.extend(['--output-dir', output_dir])

    args = generate_buildbot_json.BBJSONGenerator.parse_args(generator_args)
    generator = generate_buildbot_json.BBJSONGenerator(args)
    generator.load_configuration_files()
    generator.resolve_configuration_files()

    mixin_content = _generate_mixins_pyl(generator)
    _write_or_verify_file(MIXIN_FILEPATH, mixin_content, verify_only)

    retval = generator.main()
    if retval != 0:
        raise RuntimeError(
            f'generate_buildbot_json.py failed with exit code {retval}')

    if verify_only:
        for waterfall in generator.waterfalls:
            json_filename = waterfall['name'] + '.json'
            with open(os.path.join(output_dir, json_filename),
                      encoding='utf-8') as infile:
                new_content = infile.read()
            existing_filepath = os.path.join(THIS_DIR, json_filename)
            _write_or_verify_file(existing_filepath, new_content, verify_only)


def _parse_args() -> Tuple[argparse.Namespace, List[str]]:
    """Parses known and unknown args."""
    parser = argparse.ArgumentParser(
        'Generate //testing/buildbot JSON files. Unknown args will be passed '
        'on to the underlying generate_buildbot_json.py script.')
    parser.add_argument('--verify-only',
                        action='store_true',
                        default=False,
                        help=('Only verify that generated files are up to '
                              'date without writing new ones to disk.'))
    args, unknown_args = parser.parse_known_args()
    return args, unknown_args


def main() -> None:
    args, unknown_args = _parse_args()
    if args.verify_only:
        with tempfile.TemporaryDirectory() as temp_dir:
            _run_generator(unknown_args, temp_dir)
    else:
        _run_generator(unknown_args)


if __name__ == '__main__':
    main()
