"""Shared OS X support functions."""

import os
import re
import sys

__all__ = [
    'compiler_fixup',
    'customize_config_vars',
    'customize_compiler',
    'get_platform_osx',
]

# configuration variables that may contain universal build flags,
# like "-arch" or "-isdkroot", that may need customization for
# the user environment
_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS',
                            'BLDSHARED', 'LDSHARED', 'CC', 'CXX',
                            'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
                            'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS')

# configuration variables that may contain compiler calls
_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX')

# prefix added to original configuration variable names
_INITPRE = '_OSX_SUPPORT_INITIAL_'


def _find_executable(executable, path=None):
    """Tries to find 'executable' in the directories listed in 'path'.

    A string listing directories separated by 'os.pathsep'; defaults to
    os.environ['PATH'].  Returns the complete filename or None if not found.
    """
    if path is None:
        path = os.environ['PATH']

    paths = path.split(os.pathsep)
    base, ext = os.path.splitext(executable)

    if (sys.platform == 'win32') and (ext != '.exe'):
        executable = executable + '.exe'

    if not os.path.isfile(executable):
        for p in paths:
            f = os.path.join(p, executable)
            if os.path.isfile(f):
                # the file exists, we have a shot at spawn working
                return f
        return None
    else:
        return executable


def _read_output(commandstring, capture_stderr=False):
    """Output from successful command execution or None"""
    # Similar to os.popen(commandstring, "r").read(),
    # but without actually using os.popen because that
    # function is not usable during python bootstrap.
    # tempfile is also not available then.
    import contextlib
    try:
        import tempfile
        fp = tempfile.NamedTemporaryFile()
    except ImportError:
        fp = open("/tmp/_osx_support.%s"%(
            os.getpid(),), "w+b")

    with contextlib.closing(fp) as fp:
        if capture_stderr:
            cmd = "%s >'%s' 2>&1" % (commandstring, fp.name)
        else:
            cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
        return fp.read().decode('utf-8').strip() if not os.system(cmd) else None


def _find_build_tool(toolname):
    """Find a build tool on current path or using xcrun"""
    return (_find_executable(toolname)
                or _read_output("/usr/bin/xcrun -find %s" % (toolname,))
                or ''
            )

_SYSTEM_VERSION = None

def _get_system_version():
    """Return the OS X system version as a string"""
    # Reading this plist is a documented way to get the system
    # version (see the documentation for the Gestalt Manager)
    # We avoid using platform.mac_ver to avoid possible bootstrap issues during
    # the build of Python itself (distutils is used to build standard library
    # extensions).

    global _SYSTEM_VERSION

    if _SYSTEM_VERSION is None:
        _SYSTEM_VERSION = ''
        try:
            f = open('/System/Library/CoreServices/SystemVersion.plist', encoding="utf-8")
        except OSError:
            # We're on a plain darwin box, fall back to the default
            # behaviour.
            pass
        else:
            try:
                m = re.search(r'<key>ProductUserVisibleVersion</key>\s*'
                              r'<string>(.*?)</string>', f.read())
            finally:
                f.close()
            if m is not None:
                _SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2])
            # else: fall back to the default behaviour

    return _SYSTEM_VERSION

_SYSTEM_VERSION_TUPLE = None
def _get_system_version_tuple():
    """
    Return the macOS system version as a tuple

    The return value is safe to use to compare
    two version numbers.
    """
    global _SYSTEM_VERSION_TUPLE
    if _SYSTEM_VERSION_TUPLE is None:
        osx_version = _get_system_version()
        if osx_version:
            try:
                _SYSTEM_VERSION_TUPLE = tuple(int(i) for i in osx_version.split('.'))
            except ValueError:
                _SYSTEM_VERSION_TUPLE = ()

    return _SYSTEM_VERSION_TUPLE


def _remove_original_values(_config_vars):
    """Remove original unmodified values for testing"""
    # This is needed for higher-level cross-platform tests of get_platform.
    for k in list(_config_vars):
        if k.startswith(_INITPRE):
            del _config_vars[k]

def _save_modified_value(_config_vars, cv, newvalue):
    """Save modified and original unmodified value of configuration var"""

    oldvalue = _config_vars.get(cv, '')
    if (oldvalue != newvalue) and (_INITPRE + cv not in _config_vars):
        _config_vars[_INITPRE + cv] = oldvalue
    _config_vars[cv] = newvalue


_cache_default_sysroot = None
def _default_sysroot(cc):
    """ Returns the root of the default SDK for this system, or '/' """
    global _cache_default_sysroot

    if _cache_default_sysroot is not None:
        return _cache_default_sysroot

    contents = _read_output('%s -c -E -v - </dev/null' % (cc,), True)
    in_incdirs = False
    for line in contents.splitlines():
        if line.startswith("#include <...>"):
            in_incdirs = True
        elif line.startswith("End of search list"):
            in_incdirs = False
        elif in_incdirs:
            line = line.strip()
            if line == '/usr/include':
                _cache_default_sysroot = '/'
            elif line.endswith(".sdk/usr/include"):
                _cache_default_sysroot = line[:-12]
    if _cache_default_sysroot is None:
        _cache_default_sysroot = '/'

    return _cache_default_sysroot

def _supports_universal_builds():
    """Returns True if universal builds are supported on this system"""
    # As an approximation, we assume that if we are running on 10.4 or above,
    # then we are running with an Xcode environment that supports universal
    # builds, in particular -isysroot and -arch arguments to the compiler. This
    # is in support of allowing 10.4 universal builds to run on 10.3.x systems.

    osx_version = _get_system_version_tuple()
    return bool(osx_version >= (10, 4)) if osx_version else False

def _supports_arm64_builds():
    """Returns True if arm64 builds are supported on this system"""
    # There are two sets of systems supporting macOS/arm64 builds:
    # 1. macOS 11 and later, unconditionally
    # 2. macOS 10.15 with Xcode 12.2 or later
    # For now the second category is ignored.
    osx_version = _get_system_version_tuple()
    return osx_version >= (11, 0) if osx_version else False


def _find_appropriate_compiler(_config_vars):
    """Find appropriate C compiler for extension module builds"""

    # Issue #13590:
    #    The OSX location for the compiler varies between OSX
    #    (or rather Xcode) releases.  With older releases (up-to 10.5)
    #    the compiler is in /usr/bin, with newer releases the compiler
    #    can only be found inside Xcode.app if the "Command Line Tools"
    #    are not installed.
    #
    #    Furthermore, the compiler that can be used varies between
    #    Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2'
    #    as the compiler, after that 'clang' should be used because
    #    gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
    #    miscompiles Python.

    # skip checks if the compiler was overridden with a CC env variable
    if 'CC' in os.environ:
        return _config_vars

    # The CC config var might contain additional arguments.
    # Ignore them while searching.
    cc = oldcc = _config_vars['CC'].split()[0]
    if not _find_executable(cc):
        # Compiler is not found on the shell search PATH.
        # Now search for clang, first on PATH (if the Command LIne
        # Tools have been installed in / or if the user has provided
        # another location via CC).  If not found, try using xcrun
        # to find an uninstalled clang (within a selected Xcode).

        # NOTE: Cannot use subprocess here because of bootstrap
        # issues when building Python itself (and os.popen is
        # implemented on top of subprocess and is therefore not
        # usable as well)

        cc = _find_build_tool('clang')

    elif os.path.basename(cc).startswith('gcc'):
        # Compiler is GCC, check if it is LLVM-GCC
        data = _read_output("'%s' --version"
                             % (cc.replace("'", "'\"'\"'"),))
        if data and 'llvm-gcc' in data:
            # Found LLVM-GCC, fall back to clang
            cc = _find_build_tool('clang')

    if not cc:
        raise SystemError(
               "Cannot locate working compiler")

    if cc != oldcc:
        # Found a replacement compiler.
        # Modify config vars using new compiler, if not already explicitly
        # overridden by an env variable, preserving additional arguments.
        for cv in _COMPILER_CONFIG_VARS:
            if cv in _config_vars and cv not in os.environ:
                cv_split = _config_vars[cv].split()
                cv_split[0] = cc if cv != 'CXX' else cc + '++'
                _save_modified_value(_config_vars, cv, ' '.join(cv_split))

    return _config_vars


def _remove_universal_flags(_config_vars):
    """Remove all universal build arguments from config vars"""

    for cv in _UNIVERSAL_CONFIG_VARS:
        # Do not alter a config var explicitly overridden by env var
        if cv in _config_vars and cv not in os.environ:
            flags = _config_vars[cv]
            flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII)
            flags = re.sub(r'-isysroot\s*\S+', ' ', flags)
            _save_modified_value(_config_vars, cv, flags)

    return _config_vars


def _remove_unsupported_archs(_config_vars):
    """Remove any unsupported archs from config vars"""
    # Different Xcode releases support different sets for '-arch'
    # flags. In particular, Xcode 4.x no longer supports the
    # PPC architectures.
    #
    # This code automatically removes '-arch ppc' and '-arch ppc64'
    # when these are not supported. That makes it possible to
    # build extensions on OSX 10.7 and later with the prebuilt
    # 32-bit installer on the python.org website.

    # skip checks if the compiler was overridden with a CC env variable
    if 'CC' in os.environ:
        return _config_vars

    if re.search(r'-arch\s+ppc', _config_vars['CFLAGS']) is not None:
        # NOTE: Cannot use subprocess here because of bootstrap
        # issues when building Python itself
        status = os.system(
            """echo 'int main{};' | """
            """'%s' -c -arch ppc -x c -o /dev/null /dev/null 2>/dev/null"""
            %(_config_vars['CC'].replace("'", "'\"'\"'"),))
        if status:
            # The compile failed for some reason.  Because of differences
            # across Xcode and compiler versions, there is no reliable way
            # to be sure why it failed.  Assume here it was due to lack of
            # PPC support and remove the related '-arch' flags from each
            # config variables not explicitly overridden by an environment
            # variable.  If the error was for some other reason, we hope the
            # failure will show up again when trying to compile an extension
            # module.
            for cv in _UNIVERSAL_CONFIG_VARS:
                if cv in _config_vars and cv not in os.environ:
                    flags = _config_vars[cv]
                    flags = re.sub(r'-arch\s+ppc\w*\s', ' ', flags)
                    _save_modified_value(_config_vars, cv, flags)

    return _config_vars


def _override_all_archs(_config_vars):
    """Allow override of all archs with ARCHFLAGS env var"""
    # NOTE: This name was introduced by Apple in OSX 10.5 and
    # is used by several scripting languages distributed with
    # that OS release.
    if 'ARCHFLAGS' in os.environ:
        arch = os.environ['ARCHFLAGS']
        for cv in _UNIVERSAL_CONFIG_VARS:
            if cv in _config_vars and '-arch' in _config_vars[cv]:
                flags = _config_vars[cv]
                flags = re.sub(r'-arch\s+\w+\s', ' ', flags)
                flags = flags + ' ' + arch
                _save_modified_value(_config_vars, cv, flags)

    return _config_vars


def _check_for_unavailable_sdk(_config_vars):
    """Remove references to any SDKs not available"""
    # If we're on OSX 10.5 or later and the user tries to
    # compile an extension using an SDK that is not present
    # on the current machine it is better to not use an SDK
    # than to fail.  This is particularly important with
    # the standalone Command Line Tools alternative to a
    # full-blown Xcode install since the CLT packages do not
    # provide SDKs.  If the SDK is not present, it is assumed
    # that the header files and dev libs have been installed
    # to /usr and /System/Library by either a standalone CLT
    # package or the CLT component within Xcode.
    cflags = _config_vars.get('CFLAGS', '')
    m = re.search(r'-isysroot\s*(\S+)', cflags)
    if m is not None:
        sdk = m.group(1)
        if not os.path.exists(sdk):
            for cv in _UNIVERSAL_CONFIG_VARS:
                # Do not alter a config var explicitly overridden by env var
                if cv in _config_vars and cv not in os.environ:
                    flags = _config_vars[cv]
                    flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags)
                    _save_modified_value(_config_vars, cv, flags)

    return _config_vars


def compiler_fixup(compiler_so, cc_args):
    """
    This function will strip '-isysroot PATH' and '-arch ARCH' from the
    compile flags if the user has specified one them in extra_compile_flags.

    This is needed because '-arch ARCH' adds another architecture to the
    build, without a way to remove an architecture. Furthermore GCC will
    barf if multiple '-isysroot' arguments are present.
    """
    stripArch = stripSysroot = False

    compiler_so = list(compiler_so)

    if not _supports_universal_builds():
        # OSX before 10.4.0, these don't support -arch and -isysroot at
        # all.
        stripArch = stripSysroot = True
    else:
        stripArch = '-arch' in cc_args
        stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot'))

    if stripArch or 'ARCHFLAGS' in os.environ:
        while True:
            try:
                index = compiler_so.index('-arch')
                # Strip this argument and the next one:
                del compiler_so[index:index+2]
            except ValueError:
                break

    elif not _supports_arm64_builds():
        # Look for "-arch arm64" and drop that
        for idx in reversed(range(len(compiler_so))):
            if compiler_so[idx] == '-arch' and compiler_so[idx+1] == "arm64":
                del compiler_so[idx:idx+2]

    if 'ARCHFLAGS' in os.environ and not stripArch:
        # User specified different -arch flags in the environ,
        # see also distutils.sysconfig
        compiler_so = compiler_so + os.environ['ARCHFLAGS'].split()

    if stripSysroot:
        while True:
            indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]
            if not indices:
                break
            index = indices[0]
            if compiler_so[index] == '-isysroot':
                # Strip this argument and the next one:
                del compiler_so[index:index+2]
            else:
                # It's '-isysroot/some/path' in one arg
                del compiler_so[index:index+1]

    # Check if the SDK that is used during compilation actually exists,
    # the universal build requires the usage of a universal SDK and not all
    # users have that installed by default.
    sysroot = None
    argvar = cc_args
    indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')]
    if not indices:
        argvar = compiler_so
        indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')]

    for idx in indices:
        if argvar[idx] == '-isysroot':
            sysroot = argvar[idx+1]
            break
        else:
            sysroot = argvar[idx][len('-isysroot'):]
            break

    if sysroot and not os.path.isdir(sysroot):
        sys.stderr.write(f"Compiling with an SDK that doesn't seem to exist: {sysroot}\n")
        sys.stderr.write("Please check your Xcode installation\n")
        sys.stderr.flush()

    return compiler_so


def customize_config_vars(_config_vars):
    """Customize Python build configuration variables.

    Called internally from sysconfig with a mutable mapping
    containing name/value pairs parsed from the configured
    makefile used to build this interpreter.  Returns
    the mapping updated as needed to reflect the environment
    in which the interpreter is running; in the case of
    a Python from a binary installer, the installed
    environment may be very different from the build
    environment, i.e. different OS levels, different
    built tools, different available CPU architectures.

    This customization is performed whenever
    distutils.sysconfig.get_config_vars() is first
    called.  It may be used in environments where no
    compilers are present, i.e. when installing pure
    Python dists.  Customization of compiler paths
    and detection of unavailable archs is deferred
    until the first extension module build is
    requested (in distutils.sysconfig.customize_compiler).

    Currently called from distutils.sysconfig
    """

    if not _supports_universal_builds():
        # On Mac OS X before 10.4, check if -arch and -isysroot
        # are in CFLAGS or LDFLAGS and remove them if they are.
        # This is needed when building extensions on a 10.3 system
        # using a universal build of python.
        _remove_universal_flags(_config_vars)

    # Allow user to override all archs with ARCHFLAGS env var
    _override_all_archs(_config_vars)

    # Remove references to sdks that are not found
    _check_for_unavailable_sdk(_config_vars)

    return _config_vars


def customize_compiler(_config_vars):
    """Customize compiler path and configuration variables.

    This customization is performed when the first
    extension module build is requested
    in distutils.sysconfig.customize_compiler).
    """

    # Find a compiler to use for extension module builds
    _find_appropriate_compiler(_config_vars)

    # Remove ppc arch flags if not supported here
    _remove_unsupported_archs(_config_vars)

    # Allow user to override all archs with ARCHFLAGS env var
    _override_all_archs(_config_vars)

    return _config_vars


def get_platform_osx(_config_vars, osname, release, machine):
    """Filter values for get_platform()"""
    # called from get_platform() in sysconfig and distutils.util
    #
    # For our purposes, we'll assume that the system version from
    # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
    # to. This makes the compatibility story a bit more sane because the
    # machine is going to compile and link as if it were
    # MACOSX_DEPLOYMENT_TARGET.

    macver = _config_vars.get('MACOSX_DEPLOYMENT_TARGET', '')
    macrelease = _get_system_version() or macver
    macver = macver or macrelease

    if macver:
        release = macver
        osname = "macosx"

        # Use the original CFLAGS value, if available, so that we
        # return the same machine type for the platform string.
        # Otherwise, distutils may consider this a cross-compiling
        # case and disallow installs.
        cflags = _config_vars.get(_INITPRE+'CFLAGS',
                                    _config_vars.get('CFLAGS', ''))
        if macrelease:
            try:
                macrelease = tuple(int(i) for i in macrelease.split('.')[0:2])
            except ValueError:
                macrelease = (10, 3)
        else:
            # assume no universal support
            macrelease = (10, 3)

        if (macrelease >= (10, 4)) and '-arch' in cflags.strip():
            # The universal build will build fat binaries, but not on
            # systems before 10.4

            machine = 'fat'

            archs = re.findall(r'-arch\s+(\S+)', cflags)
            archs = tuple(sorted(set(archs)))

            if len(archs) == 1:
                machine = archs[0]
            elif archs == ('arm64', 'x86_64'):
                machine = 'universal2'
            elif archs == ('i386', 'ppc'):
                machine = 'fat'
            elif archs == ('i386', 'x86_64'):
                machine = 'intel'
            elif archs == ('i386', 'ppc', 'x86_64'):
                machine = 'fat3'
            elif archs == ('ppc64', 'x86_64'):
                machine = 'fat64'
            elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
                machine = 'universal'
            else:
                raise ValueError(
                   "Don't know machine value for archs=%r" % (archs,))

        elif machine == 'i386':
            # On OSX the machine type returned by uname is always the
            # 32-bit variant, even if the executable architecture is
            # the 64-bit variant
            if sys.maxsize >= 2**32:
                machine = 'x86_64'

        elif machine in ('PowerPC', 'Power_Macintosh'):
            # Pick a sane name for the PPC architecture.
            # See 'i386' case
            if sys.maxsize >= 2**32:
                machine = 'ppc64'
            else:
                machine = 'ppc'

    return (osname, release, machine)
