# 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."""

import dataclasses
from typing import Any

from PB.recipe_modules.pigweed.bazel.options import Options
from RECIPE_MODULES.pigweed.checkout import api as checkout_api

from recipe_engine import config_types, recipe_api


# This is copied from bazel.json in Pigweed, but there's no need to keep it
# up-to-date.
_JSON_TEST_DATA: dict[str, Any] = {
    "included_files": [],
    "packages": [
        {
            "path": "fuchsia/third_party/bazel/${platform}",
            "platforms": ["linux-amd64", "mac-amd64", "windows-amd64"],
            "tags": ["version:2@6.3.0.6"],
            "version_file": ".versions/bazel.cipd_version",
        },
        {
            "path": "flutter/java/openjdk/${platform}",
            "platforms": [
                "linux-amd64",
                "mac-amd64",
                "mac-arm64",
                "windows-amd64",
            ],
            "tags": ["version:17"],
        },
    ],
}


@dataclasses.dataclass
class BazelRunner:
    api: recipe_api.RecipeApi
    checkout_root: config_types.Path
    options: Options
    _bazel: config_types.Path | None = None

    def _ensure_cipd(self) -> config_types.Path:
        # read_json in a few lines requires absolute, normalized paths.
        json_path: config_types.Path = self.api.path.abspath(
            self.checkout_root / self.options.cipd_json_path
        )

        ensure_file = self.api.cipd.EnsureFile()
        for package in self.api.file.read_json(
            f'read {self.api.path.basename(json_path)}',
            json_path,
            test_data=_JSON_TEST_DATA,
        )["packages"]:
            ensure_file.add_package(package['path'], package['tags'][0])

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

    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

        if self.options.cipd_json_path:
            self._bazel = self._ensure_cipd()
        else:
            self._bazel = self._ensure_bazelisk()

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

    def run(self, **kwargs) -> None:
        name: str = ' '.join(['bazel'] + list(self.options.args))
        with self.api.context(cwd=self.checkout_root):
            if self.options.args:
                self.api.step(
                    name, [self.ensure(), *self.options.args], **kwargs
                )

            for invocation in self.options.invocations:
                assert invocation.args
                name: str = ' '.join(['bazel'] + list(invocation.args))
                self.api.step(name, [self.ensure(), *invocation.args], **kwargs)


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

    BazelRunner = BazelRunner

    def new_runner(
        self,
        checkout: checkout_api.CheckoutContext,
        options: Options,
    ) -> BazelRunner:
        return BazelRunner(self.m, checkout.root, options)
