# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""The `macos_sdk` module provides safe functions to access a semi-hermetic XCode
installation.

Available only to Google-run bots.
"""

from contextlib import contextmanager

from recipe_engine import recipe_api


class MacOSSDKApi(recipe_api.RecipeApi):
    """API for using OS X SDK distributed via CIPD."""

    def __init__(self, sdk_dir, version, cipd_package, cipd_version, *args, **kwargs):
        super(MacOSSDKApi, self).__init__(*args, **kwargs)

        self._sdk_dir = sdk_dir
        self._sdk_version = version.lower()
        self._cipd_package = cipd_package
        self._cipd_version = cipd_version

        self._mac_toolchain = None

    @property
    def sdk_dir(self):
        assert self._sdk_dir
        return self._sdk_dir

    @contextmanager
    def __call__(self, kind="mac", additional_sdks=None):
        """Sets up the XCode SDK environment.

        This call is a no-op on non-Mac platforms.

        This will deploy the helper tool and the XCode.app bundle at
        `[START_DIR]/cache/macos_sdk`.

        To avoid machines rebuilding these on every run, set up a named cache in
        your cr-buildbucket.cfg file like:

            caches: {
              # Cache for mac_toolchain tool and XCode.app
              name: "macos_sdk"
              path: "macos_sdk"
            }

        If you have builders which e.g. use a non-current SDK, you can give them
        a uniqely named cache:

            caches: {
              # Cache for N-1 version mac_toolchain tool and XCode.app
              name: "macos_sdk_old"
              path: "macos_sdk"
            }

        Usage:
          with api.macos_sdk():
            # sdk with mac build bits

        Args:
          kind (str): A type of SDK to install, can be mac or ios (default: mac).
          additional_sdks (List(tuple)): A list of (sdk_version, xcode_version)
            where xcode_version contains the sdk_version to be installed in the
            selected XCode.

        Raises:
          StepFailure or InfraFailure.
        """
        if not self.m.platform.is_mac:
            yield
            return
        try:
            with self.m.context(infra_steps=True), self.m.step.nest(
                "ensure XCode %s" % self._sdk_version
            ):
                cache_dir = self.m.path["cache"].join("macos_sdk")
                if not self._mac_toolchain:
                    self._mac_toolchain = self.m.cipd.ensure_tool(
                        self._cipd_package, self._cipd_version
                    )
                if not self._sdk_dir:
                    self._sdk_dir = self._ensure_xcode(
                        kind, self._sdk_version, cache_dir
                    )
                for sdk_version, xcode_version in additional_sdks or []:
                    self._ensure_sdk(kind, sdk_version, xcode_version, cache_dir)
                self.m.step(
                    "select XCode %s" % self._sdk_version,
                    ["sudo", "xcode-select", "--switch", self._sdk_dir],
                )
            yield
        finally:
            with self.m.context(infra_steps=True):
                self.m.step("reset XCode", ["sudo", "xcode-select", "--reset"])

    def _ensure_xcode(self, kind, version, dir):
        """Ensures the MacOS SDK packages are installed.

        Args:
          kind (str): A type of SDK to install, can be mac or ios.
          version (str): The XCode version to install.
          dir (str): The directory to install XCode into.

        Returns:
          Path to the installed XCode bundle.
        """
        assert kind in ("mac", "ios"), "invalid kind"
        sdk_dir = dir.join("XCode.app")
        self.m.step(
            "install XCode %s" % version,
            [
                self._mac_toolchain,
                "install",
                "-kind",
                kind,
                "-xcode-version",
                version,
                "-output-dir",
                sdk_dir,
            ],
        )
        return sdk_dir

    def _ensure_sdk(self, kind, sdk_version, xcode_version, cache_dir):
        """Ensures SDK package is installed.

        Args:
          kind (str): A type of SDK to install, can be mac or ios.
          sdk_version (str): The SDK to install.
          xcode_version (str): The XCode version that contains the SDK.
          cache_dir (str): The directory to install XCode into.
        """
        xcode_dir = cache_dir.join(xcode_version)
        sdk_path_part = [
            "Contents",
            "Developer",
            "Platforms",
            "MacOSX.platform",
            "Developer",
            "SDKs",
        ]
        sdk_path = cache_dir.join("XCode.app", *sdk_path_part).join(sdk_version)
        if not self.m.path.exists(sdk_path):
            self._ensure_xcode(kind, xcode_version, xcode_dir)
            self.m.file.symlink(
                "install %s" % sdk_version,
                xcode_dir.join("XCode.app", *sdk_path_part).join("MacOSX.sdk"),
                sdk_path,
            )
