# 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 recipe_engine import recipe_api


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

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

    @property
    def platform(self):
        if self._platform:
            return self._platform
        operating_system = self.m.platform.name.replace('win', 'windows')
        architecture = {
            'intel': {32: '386', 64: 'amd64',},
            'arm': {32: 'armv6', 64: 'arm64',},
        }[self.m.platform.arch][self.m.platform.bits]
        self._platform = '-'.join((operating_system, architecture))
        return self._platform

    def __call__(
        self,
        cipd_path,
        package_root,
        search_tag,
        paths=(),
        repository=None,
        install_mode='copy',
        metadata=None,
        add_platform=True,
    ):
        """Create CIPD package and upload it.

    Args:
      cipd_path(str): CIPD package path
      package_root(Path): 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(dict[str,str]): primary key for revision of package
      paths(Sequence[Path]): list of files and directories to include in package
      repository(str): URL of repository, used as a CIPD tag
      install_mode(str|None): 'copy', 'symlink', or None
      metadata(list of pair|None): metadata to add to package
      add_platform(bool): 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.platform)
            cipd_path = '/'.join((cipd_path.rstrip('/'), self.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,
        )
