# 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 collections.abc import Sequence

from recipe_engine import config_types, recipe_api

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

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) -> None:
        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,
    ) -> None:
        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,
        )
