# Copyright 2020 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.
"""Utility functions for uploading a cipd package."""

from __future__ import annotations

from typing import TYPE_CHECKING

from PB.recipe_modules.fuchsia.cipd_util.upload_manifest import (
    CIPDUploadManifest,
)

from recipe_engine import recipe_api

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


class CipdUploadApi(recipe_api.RecipeApi):
    """Utility functions for uploading a cipd package."""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._platform: str | None = None

    def __call__(
        self,
        cipd_path: str,
        package_root: config_types.Path,
        search_tag: dict[str, str],
        paths: Sequence[config_types.Path] = (),
        repository: str = None,
        install_mode: str | None = 'copy',
        metadata: list[tuple[str, str]] | None = None,
        add_platform: bool = True,
    ) -> str:
        """Create CIPD package and upload it.

        Args:
          cipd_path: CIPD package path
          package_root: path from which relative paths should be calculated,
            if neither package_dirs nor package_files is listed all files within
            this directory are included in the package
          search_tag: primary key for revision of package
          paths: list of files and directories to include in package
          repository: URL of repository, used as a CIPD tag
          install_mode: 'copy', 'symlink', or None
          metadata: metadata to add to package
          add_platform: add platform string to the end of cipd_path

        Returns:
          Instance id of uploaded package.
        """

        name = str(cipd_path.split('/')[-1])

        if add_platform:
            assert not cipd_path.endswith(self.m.cipd.platform)
            cipd_path = '/'.join((cipd_path.rstrip('/'), self.m.cipd.platform))

        if not paths:
            paths = [package_root]

        return self.m.cipd_util.upload_package(
            pkg_name=cipd_path,
            pkg_root=package_root,
            pkg_paths=paths,
            search_tag=search_tag,
            repository=repository,
            install_mode=install_mode,
            metadata=metadata,
            name=name,
        )

    def manifest(
        self,
        manifest_path: config_types.Path,
        build_dir: config_types.Path,
        checkout: checkout_api.CheckoutContext,
        cas_digests: dict[str, str],
        upload_to_cipd: bool,
    ):
        manifest = self.m.file.read_proto(
            f'read cipd manifest {manifest_path}',
            manifest_path,
            CIPDUploadManifest,
            codec='JSONPB',
        )

        self.m.cipd_util.upload_from_manifest(
            cipd_package=manifest.pkg_name,
            cipd_manifest=manifest,
            build_dir=build_dir,
            repository=checkout.options.remote,
            git_revision=checkout.revision(),
            upload_to_cipd=upload_to_cipd,
            cas_digests=cas_digests,
        )
