# Copyright 2023 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Bazel-related functions."""

from __future__ import annotations

import dataclasses
import shlex
import re
from typing import TYPE_CHECKING

from PB.recipe_modules.pigweed.bazel.options import Options
from recipe_engine import recipe_api

if TYPE_CHECKING:  # pragma: no cover
    from recipe_engine import config_types
    from RECIPE_MODULES.pigweed.checkout import api as checkout_api


@dataclasses.dataclass
class BazelRunner:
    api: recipe_api.RecipeApi
    checkout: checkout_api.CheckoutContext
    options: Options
    _bazel: config_types.Path | None = None
    continue_after_build_error: bool = False

    def _ensure_bazelisk(self) -> config_types.Path:
        ensure_file = self.api.cipd.EnsureFile()
        ensure_file.add_package(
            'fuchsia/third_party/bazelisk/${platform}',
            self.options.bazelisk_version or 'latest',
        )

        root = self.api.path.mkdtemp()
        self.api.cipd.ensure(root, ensure_file, name='ensure bazelisk')
        return root / 'bazelisk'

    def ensure(self) -> config_types.Path:
        if self._bazel:
            return self._bazel

        self._bazel = self._ensure_bazelisk()

        self.api.step('bazel version', [self._bazel, 'version'])
        return self._bazel

    def _override_args(self) -> list[str]:
        if self.api.path.exists(self.checkout.root / 'MODULE.bazel'):
            # We're in a bzlmod-managed workspace.
            flag = "--override_module"  # pragma: no cover
        else:
            # We're in a traditional workspace.
            flag = "--override_repository"

        return [
            f'{flag}={repo}={path}'
            for repo, path in self.checkout.bazel_overrides.items()
        ]

    def run(self, **kwargs) -> None:
        config_name = self.options.config_path or 'pigweed.json'
        config_path = self.checkout.root / config_name
        self.api.path.mock_add_file(config_path)

        config = {}
        if self.api.path.isfile(config_path):
            config = self.api.file.read_json(
                f'read {config_name}',
                config_path,
                test_data={
                    'pw': {
                        'bazel_presubmit': {
                            'remote_cache': True,
                            'upload_local_results': True,
                            'programs': {
                                'default': [
                                    ['build', '//...'],
                                    ['test', '//...'],
                                ],
                            },
                        },
                    },
                },
            )
            config = config.get('pw', config).get('bazel_presubmit', config)

        base_args: list[str] = []

        # Don't limit the amount Bazel will write to stdout/stderr.
        base_args.append('--experimental_ui_max_stdouterr_bytes=-1')

        if config.get('remote'):
            # TODO: b/368128573 - Support remote execution on MacOS.
            if self.api.platform.is_linux:
                base_args.append('--config=remote')
            else:
                self.api.step.empty(
                    'ignoring remote because not running on Linux'
                )

        elif config.get('remote_cache'):
            # --config=remote already implies --config=remote_cache.
            base_args.append('--config=remote_cache')

        if self.api.buildbucket.build.builder.project == 'pigweed':
            instance_name = 'pigweed-rbe-open'
        else:
            instance_name = 'pigweed-rbe-private'

        if self.api.buildbucket_util.is_tryjob:
            instance_name += '-pre'

        base_args.append(f'--bes_instance_name={instance_name}')

        if instance_name == 'pigweed-rbe-open':
            # Ted messed up and gave the pigweed-rbe-open RBE instance a
            # different name (default-instance instead of default_instance).
            # Sadly this is annoying to fix because instances cannot be renamed,
            # and you can't have more than one instance in a GCP region.
            #
            # TODO: b/312215590 - Fix this.
            base_args.append(
                '--remote_instance_name=projects/pigweed-rbe-open/instances/default-instance'
            )
        else:
            base_args.append(
                f'--remote_instance_name=projects/{instance_name}/instances/default_instance'
            )

        if config.get('upload_local_results'):
            if not config.get('remote_cache'):
                self.api.step.empty(
                    'ignoring upload_local_results since remote_cache is False'
                )
            else:
                base_args.append('--remote_upload_local_results=true')

        base_args.extend(self._override_args())

        if self.continue_after_build_error:
            base_args.append('--keep_going')

        with (
            self.api.context(cwd=self.checkout.root),
            self.api.defer.context() as defer,
        ):
            for invocation in self.options.invocations:
                assert invocation.args
                name: str = ' '.join(['bazel'] + list(invocation.args))
                defer(
                    self.api.step,
                    name,
                    [self.ensure(), *invocation.args, *base_args],
                    **kwargs,
                )

            programs = config.get('programs', {})
            for program in self.options.program or ('default',):
                with self.api.step.nest(program):
                    assert program in programs, f'{program} not in {programs}'
                    assert programs[program]
                    for args in programs[program]:
                        json_path = self.api.path.mkdtemp() / 'metadata.json'

                        cmd = [
                            self.api.bazel.resource('wrapper.py'),
                            '--json',
                            self.api.json.output(leak_to=json_path),
                            '--',
                            self.ensure(),
                            *args,
                            *base_args,
                        ]
                        defer(
                            self.api.step,
                            shlex.join(args),
                            cmd,
                            **kwargs,
                        )

                        self.api.path.mock_add_file(json_path)
                        if self.api.path.isfile(json_path):
                            with self.api.step.nest('resultstore link') as pres:
                                data = self.api.file.read_json(
                                    'read',
                                    json_path,
                                    test_data={
                                        'resultstore': 'https://result.store/',
                                    },
                                )
                                if 'resultstore' in data:
                                    pres.links['resultstore'] = data[
                                        'resultstore'
                                    ]
                                else:  # pragma: no cover
                                    pres.step_summary_text = (
                                        'no resultstore link found'
                                    )


class BazelApi(recipe_api.RecipeApi):
    """Bazel utilities."""

    BazelRunner = BazelRunner

    def new_runner(
        self,
        checkout: checkout_api.CheckoutContext,
        options: Options | None,
        continue_after_build_error: bool = False,
    ) -> BazelRunner:
        return BazelRunner(
            self.m,
            checkout=checkout,
            options=options,
            continue_after_build_error=continue_after_build_error,
        )
