# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import platform as py_platform

from spack.operating_systems.mac_os import MacOs, mac_releases
from spack.version import Version

from ._platform import Platform


class Darwin(Platform):
    priority = 89

    binary_formats = ["macho"]

    def __init__(self):
        super().__init__("darwin")
        mac_os = MacOs()
        self.default_os = str(mac_os)
        self.add_operating_system(str(mac_os), mac_os)

        for version in mac_releases.keys():
            mac_os_version = MacOs(version)
            # This is idempotent, so it doesn't matter if it's already there
            self.add_operating_system(str(mac_os_version), mac_os_version)

    def buildable_oses(self):
        return {self.default_os}

    @classmethod
    def detect(cls):
        return "darwin" in py_platform.system().lower()

    def setup_platform_environment(self, pkg, env):
        """Specify deployment target based on target OS version.

        The ``MACOSX_DEPLOYMENT_TARGET`` environment variable provides a
        default ``-mmacosx-version-min`` argument for GCC and Clang compilers,
        as well as the default value of ``CMAKE_OSX_DEPLOYMENT_TARGET`` for
        CMake-based build systems. The default value for the deployment target
        is usually the major version (11, 10.16, ...) for CMake and Clang, but
        some versions of GCC specify a minor component as well (11.3), leading
        to numerous link warnings about inconsistent or incompatible target
        versions. Setting the environment variable ensures consistent versions
        for an install toolchain target, even when the host macOS version
        changes.

        TODO: it may be necessary to add SYSTEM_VERSION_COMPAT for older
        versions of the macosx developer tools; see
        https://github.com/spack/spack/pull/26290 for discussion.
        """

        os = self.operating_sys[pkg.spec.os]
        version = Version(os.version)
        if len(version) == 1:
            # Version has only one component: add a minor version to prevent
            # potential errors with `ld`,
            # which fails with `-macosx_version_min 11`
            # but succeeds with `-macosx_version_min 11.0`.
            # Most compilers seem to perform this translation automatically,
            # but older GCC does not.
            version = str(version) + ".0"
        env.set("MACOSX_DEPLOYMENT_TARGET", str(version))
