#!/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 = {
    'dawn_end2end_real_hardware_gtests_common_args': {
        'args': [
            '--use-gpu-in-tests',
            '--exclusive-device-type-preference=discrete,integrated',
            '--test-launcher-retry-limit=0',
            '--test-launcher-batch-limit=512',
        ],
        'linux_args': [
            '--no-xvfb',
        ],
        'win_args': [
            # TODO(crbug.com/454365243): Remove this filter when including these
            # tests does not contribute to OOM issues.
            '--gtest_filter=-*WebGPU_WebGPU_backend_on*',
        ],
    },
    'no_swarming': {
        'swarming': {
            'can_use_on_swarming_builders': False,
        },
    },
    'result_adapter_gtest_json': {
        'resultdb': {
            'result_format': 'gtest_json',
        },
    },
    'result_adapter_json': {
        'resultdb': {
            'result_format': 'json',
        },
    },
    'result_adapter_single': {
        'resultdb': {
            'result_format': 'single',
        },
    },
    'tint_ir_merge': {
        'merge': {
            'script': '//scripts/merge_scripts/generate_tint_fuzz_corpora.py',
            'args': [
                '--fuzzer-name',
                'tint_ir_fuzzer',
            ],
        },
    },
    'tint_wgsl_merge': {
        'merge': {
            'script': '//scripts/merge_scripts/generate_tint_fuzz_corpora.py',
            'args': [
                '--fuzzer-name',
                'tint_wgsl_fuzzer',
            ],
        },
    },
    'true_noop_merge': {
        'merge': {
            'script': '//scripts/merge_scripts/true_noop_merge.py',
        },
    },
    'wire_trace_merge': {
        'merge': {
            'script':
            '//scripts/merge_scripts/generate_wire_trace_fuzz_corpora.py',
            'args': [
                '--fuzzer-name',
                'dawn_wire_server_and_frontend_fuzzer',
                '--fuzzer-name',
                'dawn_wire_server_and_vulkan_backend_fuzzer',
                '--fuzzer-name',
                'dawn_wire_server_and_d3d12_backend_fuzzer',
            ],
        },
    },
}

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()
