# Copyright 2021 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.
"""Calls to build code."""

from __future__ import annotations

import dataclasses
from typing import TYPE_CHECKING

from PB.recipe_modules.pigweed.build import options as options_pb2
from recipe_engine import config_types, recipe_api

if TYPE_CHECKING:  # pragma: no cover
    from recipe_engine import step_data


@dataclasses.dataclass
class BuildContext:
    _api: recipe_api.RecipeApi
    checkout_root: config_types.Path
    root: config_types.Path
    options: options_pb2.Options


_Command = list[str | config_types.Path]


class BuildApi(recipe_api.RecipeApi):
    """Calls to build code."""

    BuildContext = BuildContext

    CAS_DIGEST_PROPERTY_NAME: str = 'cas_build_digest'

    def create(
        self,
        checkout_root: config_types.Path,
        options: options_pb2.Options,
        root: config_types.Path | None = None,
    ) -> BuildContext:
        if not root:
            root = checkout_root / 'out'
        return BuildContext(self.m, checkout_root, root, options)

    def __call__(self, ctx: BuildContext) -> None:
        self.install_packages(ctx)
        self.gn_gen(ctx)
        self.ninja(ctx)

    @recipe_api.ignore_warnings('recipe_engine/PYTHON2_DEPRECATED')
    def install_packages(self, ctx: BuildContext) -> None:
        if not ctx.options.packages:
            return

        with self.m.step.nest('install packages'):
            cmd: _Command = ['python', '-m', 'pw_cli', 'package', 'install']
            for package in ctx.options.packages:
                self.m.step(package, cmd + [package])

    def gn_gen(self, ctx: BuildContext) -> None:
        cmd: _Command = ['gn', 'gen']

        for gn_arg in ctx.options.gn_args:
            cmd.append(f'--args={gn_arg}')

        # Infrequently needed but harmless to always add this.
        cmd.append('--export-compile-commands')

        cmd.append(ctx.root)

        with self.m.context(cwd=ctx.checkout_root):
            self.m.step('gn gen', cmd)

    def get_gn_args(
        self,
        ctx: BuildContext,
        test_data=None,
    ) -> dict[str, int | str]:
        context_kwargs = {'cwd': ctx.checkout_root} if ctx.checkout_root else {}
        with self.m.context(**context_kwargs):
            cmd: _Command = ['gn', 'args', ctx.root, '--list', '--json']
            args = self.m.step(
                'all gn args',
                cmd,
                stdout=self.m.json.output(),
                step_test_data=lambda: self.m.json.test_api.output_stream(
                    test_data or []
                ),
            ).stdout
            return {x['name']: x for x in args or ()}

    def ninja(self, ctx: BuildContext) -> None:
        cmd: _Command = ['ninja', '-C', ctx.root]
        cmd.extend(ctx.options.ninja_targets)
        with self.m.default_timeout():
            self.m.step('ninja', cmd)

    def archive_to_cas(self, ctx: BuildContext) -> str:
        # TODO: b/234879756 - Only archive necessary files.
        with self.m.step.nest('archive to cas') as pres:
            digest: str = self.m.cas.archive('archive', ctx.root, ctx.root)
            pres.properties[self.CAS_DIGEST_PROPERTY_NAME] = digest
            return digest

    def download_from_cas(
        self, ctx: BuildContext, digest: str
    ) -> step_data.StepData:
        return self.m.cas.download('download from cas', digest, ctx.root)
