# Copyright 2020 The IREE Authors
#
# Licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

# This configure script wraps a normal CMake configure of the project for use
# in CI pipelines, doing some sanity checks, discovery and work-arounding.

# This future is needed to print Python2 EOL message
from __future__ import print_function
import sys

if sys.version_info < (3,):
    print("Python 2 has reached end-of-life and is no longer supported.")
    sys.exit(-1)
if sys.platform == "win32" and sys.maxsize.bit_length() == 31:
    print(
        "32-bit Windows Python runtime is not supported. Please switch to 64-bit Python."
    )
    sys.exit(-1)

import importlib
import json
import os
import platform
import subprocess
import sysconfig
import tempfile

is_windows = platform.system() == "Windows"


def display_help():
    print("Syntax: python build_tools/cmake/cmake_ci.py [--install|--build] ...")
    print("If neither --install or --build are the first argument, then it is ")
    print("assumed to be a generate invocation")


mode = "generate"
if len(sys.argv) < 2:
    display_help()
    sys.exit(1)
if sys.argv[1] == "--install":
    mode = "install"
elif sys.argv[1] == "--build":
    mode = "build"


def report(*args):
    print("--", *args)


def get_setting(varname, default_value):
    value = os.environ.get(varname)
    if value is None:
        return default_value
    return value


def get_bool_setting(varname, default_value):
    value = get_setting(varname, default_value)
    if value is True or value is False:
        return value
    return value == "" or value == "ON" or value == "1"


def which(thefile):
    path = os.environ.get("PATH", os.defpath).split(os.pathsep)
    for d in path:
        fname = os.path.join(d, thefile)
        fnames = [fname]
        if sys.platform == "win32":
            exts = os.environ.get("PATHEXT", "").split(os.pathsep)
            fnames += [fname + ext for ext in exts]
        for name in fnames:
            if os.access(name, os.F_OK | os.X_OK) and not os.path.isdir(name):
                return name
    return None


def use_tool_path(toolname, varname=None):
    if not varname:
        varname = toolname.upper()
    value = get_setting(f"USE_{varname}", "ON")
    if value.upper() == "OFF":
        return None
    if value.upper() == "ON" or value == "":
        return which(toolname)
    if os.access(value, os.F_OK | os.X_OK) and not os.path.isdir(value):
        return value


### Detect cmake.
use_cmake = use_tool_path("cmake") or "cmake"
cmake_command_prefix = [use_cmake]
cmake_environ = os.environ


def cmake_commandline(args):
    return cmake_command_prefix + args


if is_windows:
    # Bazel needs msys bash and TensorFlow will melt down and cry if it finds
    # system bash. Because, of course it will.
    # Note that we don't set this as a CMake option because it may have spaces
    # in the path, use backslashes or various other things that get corrupted
    # in the five or six layers of shoddy string transformations between here
    # and where it gets used.
    bash_exe = which("bash")
    report("Found Windows bash:", bash_exe)
    report(
        "NOTE: If the above is system32 bash and you are using bazel to build "
        "TensorFlow, you are going to have a bad time. Suggest being explicit "
        "adding the correct directory to your path. I'm really sorry. "
        "I didn't make this mess... just the messenger"
    )
    report(f'Full path = {os.environ.get("PATH")}')


def invoke_generate():
    ##############################################################################
    # Figure out where we are and where we are going.
    ##############################################################################
    repo_root = os.path.abspath(
        get_setting("REPO_DIR", os.path.join(os.path.dirname(__file__), "..", ".."))
    )
    report(f"Using REPO_DIR = {repo_root}")

    ##############################################################################
    # Load version_info.json
    ##############################################################################

    def load_version_info():
        with open(os.path.join(repo_root, "version_info.json"), "rt") as f:
            return json.load(f)

    try:
        version_info = load_version_info()
    except FileNotFoundError:
        report("version_info.json found")
        version_info = {}

    ##############################################################################
    # CMake configure.
    ##############################################################################

    cmake_args = [
        f"-S{repo_root}",
        f"-DPython3_EXECUTABLE:FILEPATH={sys.executable}",
        # The old python package settings should not be needed, but since there
        # can be configuration races between packages that use both mechanisms,
        # be explicit.
        f"-DPYTHON_EXECUTABLE:FILEPATH={sys.executable}",
        f'-DPython3_INCLUDE_DIR:PATH={sysconfig.get_path("include")}',
        f'-DPYTHON_INCLUDE_DIR:PATH={sysconfig.get_path("include")}',
        f'-DIREE_RELEASE_PACKAGE_SUFFIX:STRING={version_info.get("package-suffix") or ""}',
        f'-DIREE_RELEASE_VERSION:STRING={version_info.get("package-version") or "0.0.1a1"}',
        f'-DIREE_RELEASE_REVISION:STRING={version_info.get("iree-revision") or "HEAD"}',
    ]

    ### Detect generator.
    if use_tool_path("ninja"):
        report("Using ninja")
        cmake_args.append("-GNinja")
    elif is_windows:
        cmake_args.extend(["-G", "NMake Makefiles"])

    # Detect other build tools.
    use_ccache = use_tool_path("ccache")
    if not is_windows and use_ccache:
        report(f"Using ccache {use_ccache}")
        cmake_args.append(f"-DCMAKE_CXX_COMPILER_LAUNCHER={use_ccache}")

    # Clang
    use_clang = use_tool_path("clang")
    if not is_windows and use_clang:
        report(f"Using clang {use_clang}")
        cmake_args.append(f"-DCMAKE_C_COMPILER={use_clang}")
    use_clangcpp = use_tool_path("clang++", "CLANGCPP")
    if not is_windows and use_clangcpp:
        report(f"Using clang++ {use_clangcpp}")
        cmake_args.append(f"-DCMAKE_CXX_COMPILER={use_clangcpp}")

    # LLD
    use_lld = use_tool_path("lld")
    if not is_windows and use_lld:
        report(f"Using linker {use_lld}")
        cmake_args.append("-DIREE_ENABLE_LLD=ON")

    cmake_args.extend(sys.argv[1:])
    report(f'Running cmake (generate): {" ".join(cmake_args)}')
    subprocess.check_call(cmake_commandline(cmake_args), env=cmake_environ)


# Select which mode.
if mode == "generate":
    invoke_generate()
else:
    # Just pass-through.
    cmake_args = cmake_commandline(sys.argv[1:])
    report("Invoke CMake:", " ".join(cmake_args))
    subprocess.check_call(cmake_args, env=cmake_environ)
