# 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 Sequence, 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 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,
        )
