# swift_build_support/toolchain.py ------------------------------*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ----------------------------------------------------------------------------
"""
Represent toolchain - the versioned executables.
"""
# ----------------------------------------------------------------------------

from __future__ import absolute_import

import platform

from . import cache_util
from . import shell
from . import xcrun
from .which import which

__all__ = [
    'host_toolchain',
]


class Toolchain(object):
    """Represents native host toolchain
    """

    def find_tool(self, *names):
        raise NotImplementedError('Subclasses must implement this method')


# Declare properties for each tools.
# These properties are loaded lazily and assignable.
def _register(name, *tool):
    def _getter(self):
        return self.find_tool(*tool)
    _getter.__name__ = name
    setattr(Toolchain, name, cache_util.reify(_getter))


_register("cc", "clang")
_register("cxx", "clang++")
_register("ninja", "ninja", "ninja-build")
_register("cmake", "cmake")
_register("distcc", "distcc")
_register("distcc_pump", "distcc-pump", "pump")
_register("llvm_profdata", "llvm-profdata")
_register("llvm_cov", "llvm-cov")
_register("lipo", "lipo")
_register("libtool", "libtool")


class Darwin(Toolchain):
    def __init__(self, sdk, toolchain):
        super(Darwin, self).__init__()
        self.xcrun_sdk = sdk
        self.xcrun_toolchain = toolchain

    def find_tool(self, *names):
        for name in names:
            # NOTE: xcrun searches from developer tools directory *and* from
            #       PATH. Relatively slow, but we don't need `which` for
            #       Darwin.
            found = xcrun.find(name,
                               sdk=self.xcrun_sdk,
                               toolchain=self.xcrun_toolchain)
            if found is not None:
                return found
        return None


class GenericUnix(Toolchain):
    def __init__(self, suffixes):
        super(GenericUnix, self).__init__()

        # On these platforms, search 'clang', 'clang++' unconditionally.
        # To determine the llvm_suffix.
        ret = self.find_clang(['clang', 'clang++'], suffixes)
        if ret is None:
            self.cc = None
            self.cxx = None
            # We don't have clang, then we don't have any llvm tools.
            self.llvm_suffixes = []
        else:
            found, suffix = ret
            self.cc, self.cxx = found

            if suffix == '':
                # Some platform may have `clang`, `clang++`, `llvm-cov-3.6`
                # but not `llvm-cov`. In that case, we assume `clang` is
                # corresponding to the best version of llvm tools found.
                self.llvm_suffixes = suffixes
            else:
                # Otherwise, we must have llvm tools with the same suffix as
                # `clang` or `clang++`
                self.llvm_suffixes = [suffix]

    def find_clang(self, tools, suffixes):
        for suffix in suffixes:
            ret = [which(t + suffix) for t in tools]
            if all(t is not None for t in ret):
                return (ret, suffix)
        return None

    def find_llvm_tool(self, tool):
        for suffix in self.llvm_suffixes:
            found = which(tool + suffix)
            if found is not None:
                # If we found the tool with the suffix, lock suffixes to it.
                self.llvm_suffix = [suffix]
                return found
        return None

    def find_tool(self, *names):
        for name in names:
            if name.startswith('llvm-'):
                found = self.find_llvm_tool(name)
            else:
                found = which(name)
            if found is not None:
                return found
        return None


class MacOSX(Darwin):
    def __init__(self, toolchain='default'):
        super(MacOSX, self).__init__(sdk='macosx', toolchain=toolchain)


class Linux(GenericUnix):
    def __init__(self):
        super(Linux, self).__init__(['', '-3.8', '-3.7', '-3.6', '-3.5'])


class FreeBSD(GenericUnix):
    def __init__(self):
        # For testing toolchain initializer on non-FreeBSD systems
        sys = platform.system()
        if sys != 'FreeBSD':
            suffixes = ['']
        # See: https://github.com/apple/swift/pull/169
        # Building Swift from source requires a recent version of the Clang
        # compiler with C++14 support.
        elif self._release_date and self._release_date >= 1100000:
            suffixes = ['']
        else:
            suffixes = ['38', '37', '36', '35']
        super(FreeBSD, self).__init__(suffixes)

    @cache_util.reify
    def _release_date(self):
        """Return the release date for FreeBSD operating system on this host.
        If the release date cannot be ascertained, return None.
        """
        # For details on `sysctl`, see:
        # http://www.freebsd.org/cgi/man.cgi?sysctl(8)
        out = shell.capture(['sysctl', '-n', 'kern.osreldate'],
                            dry_run=False, echo=False, optional=True)
        if out is None:
            return None
        return int(out)


class Cygwin(Linux):
    # Currently, Cygwin is considered as the same as Linux.
    pass


def host_toolchain(**kwargs):
    sys = platform.system()
    if sys == 'Darwin':
        return MacOSX(kwargs.pop('xcrun_toolchain', 'default'))
    elif sys == 'Linux':
        return Linux()
    elif sys == 'FreeBSD':
        return FreeBSD()
    elif sys.startswith('CYGWIN'):
        return Cygwin()
    else:
        raise NotImplementedError('The platform "%s" does not have a defined '
                                  'toolchain.' % sys)
