# utils/SwiftBuildSupport.py - Utilities for Swift build scripts -*- 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

from __future__ import print_function

try:
    # Python 2
    import ConfigParser
except ImportError:
    # Python 3
    import configparser as ConfigParser

import os

from . import diagnostics


HOME = os.environ.get("HOME", "/")


def _get_default_source_root():
    result = ""

    # Are we in a Swift checkout? Start from this file and check its parent
    # directories.
    #
    # $SWIFT_SOURCE_ROOT/swift/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py
    utils_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    (swift_path, parent_dirname) = os.path.split(utils_path)
    if parent_dirname != "utils":
        return result
    if not os.path.exists(os.path.join(swift_path, 'CMakeLists.txt')):
        return result
    result = os.path.dirname(swift_path)

    # Are we in an LLVM checkout? Start from the Swift checkout and check /its/
    # parent directories.
    #
    # $SWIFT_SOURCE_ROOT/llvm/tools/swift/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py
    (llvm_path, parent_dirname) = os.path.split(result)
    if parent_dirname != "tools":
        return result
    if not os.path.exists(os.path.join(llvm_path, 'CMakeLists.txt')):
        return result
    result = os.path.dirname(llvm_path)

    return result


# Set SWIFT_SOURCE_ROOT in your environment to control where the sources
# are found.
SWIFT_SOURCE_ROOT = os.environ.get(
    "SWIFT_SOURCE_ROOT", _get_default_source_root())

# Set SWIFT_BUILD_ROOT to a directory that will contain a subdirectory
# for each build configuration
SWIFT_BUILD_ROOT = os.environ.get(
    "SWIFT_BUILD_ROOT", os.path.join(SWIFT_SOURCE_ROOT, "build"))


def _get_default_swift_repo_name():
    result = ""

    # Are we in a Swift checkout? Start from this file and check its parent
    # directories.
    #
    # $SWIFT_SOURCE_ROOT/$SWIFT_REPO_NAME/utils/swift_build_support/swift_build_support/SwiftBuildSupport.py
    utils_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    (swift_path, parent_dirname) = os.path.split(utils_path)
    if parent_dirname != "utils":
        return result
    if not os.path.exists(os.path.join(swift_path, 'CMakeLists.txt')):
        return result
    (_, swift_repo_name) = os.path.split(swift_path)
    return swift_repo_name


# Set SWIFT_REPO_NAME in your environment to control the name of the swift
# directory name that is used.
SWIFT_REPO_NAME = os.environ.get(
    "SWIFT_REPO_NAME", _get_default_swift_repo_name())


def _load_preset_files_impl(preset_file_names, substitutions={}):
    config = ConfigParser.SafeConfigParser(substitutions, allow_no_value=True)
    if config.read(preset_file_names) == []:
        diagnostics.fatal(
            "preset file not found (tried " + str(preset_file_names) + ")")
    return config


_PRESET_PREFIX = "preset: "


def _get_preset_options_impl(config, substitutions, preset_name):
    section_name = _PRESET_PREFIX + preset_name
    if section_name not in config.sections():
        return (None, None, None)

    build_script_opts = []
    build_script_impl_opts = []
    missing_opts = []
    dash_dash_seen = False

    for o in config.options(section_name):
        try:
            a = config.get(section_name, o)
        except ConfigParser.InterpolationMissingOptionError as e:
            # e.reference contains the correctly formatted option
            missing_opts.append(e.reference)
            continue

        if not a:
            a = ""

        if o in substitutions:
            continue

        opt = None
        if o == "mixin-preset":
            # Split on newlines and filter out empty lines.
            mixins = filter(None, [m.strip() for m in a.splitlines()])
            for mixin in mixins:
                (base_build_script_opts,
                    base_build_script_impl_opts,
                    base_missing_opts) = \
                    _get_preset_options_impl(config, substitutions, mixin)
                build_script_opts += base_build_script_opts
                build_script_impl_opts += base_build_script_impl_opts
                missing_opts += base_missing_opts
        elif o == "dash-dash":
            dash_dash_seen = True
        elif a == "":
            opt = "--" + o
        else:
            opt = "--" + o + "=" + a

        if opt:
            if not dash_dash_seen:
                build_script_opts.append(opt)
            else:
                build_script_impl_opts.append(opt)

    return (build_script_opts, build_script_impl_opts, missing_opts)


def get_preset_options(substitutions, preset_file_names, preset_name):
    config = _load_preset_files_impl(preset_file_names, substitutions)

    (build_script_opts, build_script_impl_opts, missing_opts) = \
        _get_preset_options_impl(config, substitutions, preset_name)
    if not build_script_opts and not build_script_impl_opts:
        diagnostics.fatal("preset '" + preset_name + "' not found")
    if missing_opts:
        diagnostics.fatal("missing option(s) for preset '" + preset_name +
                          "': " + ", ".join(missing_opts))

    # Migrate 'swift-sdks' parameter to 'stdlib-deployment-targets'
    swift_sdks_opts = [opt for opt in build_script_impl_opts
                       if opt.startswith("--swift-sdks")]
    try:
        swift_sdks_opt = swift_sdks_opts[-1]
    except IndexError:
        swift_sdks_opt = None

    if swift_sdks_opt is not None:
        sdks_to_configure = swift_sdks_opt.split("=")[1].split(";")
        tgts = []
        # Expand SDKs in to their deployment targets
        from swift_build_support.swift_build_support.targets \
            import StdlibDeploymentTarget
        for sdk in sdks_to_configure:
            if sdk == "OSX":
                tgts += StdlibDeploymentTarget.OSX.targets
            elif sdk == "IOS":
                tgts += StdlibDeploymentTarget.iOS.targets
            elif sdk == "IOS_SIMULATOR":
                tgts += StdlibDeploymentTarget.iOSSimulator.targets
            elif sdk == "TVOS":
                tgts += StdlibDeploymentTarget.AppleTV.targets
            elif sdk == "TVOS_SIMULATOR":
                tgts += StdlibDeploymentTarget.AppleTVSimulator.targets
            elif sdk == "WATCHOS":
                tgts += StdlibDeploymentTarget.AppleWatch.targets
            elif sdk == "WATCHOS_SIMULATOR":
                tgts += StdlibDeploymentTarget.AppleWatchSimulator.targets

        build_script_opts.append("--stdlib-deployment-targets=" +
                                 " ".join([tgt.name for tgt in tgts]))

    # Filter the swift-sdks parameter
    build_script_impl_opts = [opt for opt in build_script_impl_opts
                              if not opt.startswith("--swift-sdks")]

    return build_script_opts + ["--"] + build_script_impl_opts


def get_all_preset_names(preset_file_names):
    config = _load_preset_files_impl(preset_file_names)
    return [name[len(_PRESET_PREFIX):] for name in config.sections()
            if name.startswith(_PRESET_PREFIX)]
