#!/usr/bin/env fuchsia-vendored-python
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import subprocess
import sys


FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(  # scripts
        os.path.dirname(os.path.abspath(__file__))  # rust
    )
)

BUILD_CONFIG = """
[llvm]
optimize = true
static-libstdcpp = true
ninja = true
targets = "X86;AArch64"

[build]
target = ["{target}-fuchsia"]
docs = false
extended = true
openssl-static = true

[install]
prefix = "{prefix}"
sysconfdir = "etc"

[rust]
optimize = true

[target.{target}-fuchsia]
cc = "{cc}"
cxx = "{cxx}"
ar = "{ar}"
linker = "{cc}"

[dist]
"""

CARGO_CONFIG = """
[target.{target}-fuchsia]
linker = "{linker}"
ar = "{ar}"
rustflags = [
    "-C", "link-arg=--target={target}-fuchsia",
    "-C", "link-arg=--sysroot={sysroot}",
    "-C", "link-arg=-L{shared_libs_root}",
]
"""


def ensure_dir(dir):
    if not os.path.exists(dir):
        os.makedirs(dir)
    return dir


def main():
    parser = argparse.ArgumentParser(
        description="Build a Rust toolchain for Fuchsia"
    )
    parser.add_argument(
        "--rust-root", help="root directory of Rust checkout", required=True
    )
    parser.add_argument(
        "--sysroot",
        help="zircon sysroot (possibly //out/release-x64/sdk/exported/zircon_sysroot/sysroot)",
        required=True,
    )
    parser.add_argument(
        "--shared-libs-root",
        help="shared libs root (possibly //out/release-x64/x64-shared)",
        required=True,
    )
    parser.add_argument(
        "--host-os",
        help="host operating system",
        choices=["linux", "mac"],
        default="linux",
    )
    parser.add_argument(
        "--target",
        help="target architecture",
        choices=["x86_64", "aarch64"],
        default="x86_64",
    )
    parser.add_argument(
        "--staging-dir",
        help="directory in which to stage Rust build configuration artifacts",
        default="/tmp/fuchsia_rustc_staging",
    )
    parser.add_argument(
        "--debug",
        help="turn on debug mode, with extra logs",
        action="store_true",
    )
    args = parser.parse_args()

    rust_root = os.path.abspath(args.rust_root)
    sysroot = os.path.abspath(args.sysroot)
    shared_libs_root = os.path.abspath(args.shared_libs_root)
    host_os = args.host_os
    target = args.target
    staging_dir = os.path.abspath(args.staging_dir)
    debug = args.debug

    build_dir = ensure_dir(os.path.join(staging_dir, "build"))
    toolchain_dir = ensure_dir(os.path.join(staging_dir, "toolchain"))
    clang_dir = os.path.join(
        FUCHSIA_ROOT, "buildtools", host_os + "-x64", "clang"
    )

    config_file = os.path.join(build_dir, "config.toml")
    with open(config_file, "w") as file:
        file.write(
            BUILD_CONFIG.format(
                target=target,
                prefix=toolchain_dir,
                cc=os.path.join(clang_dir, "bin", "clang"),
                cxx=os.path.join(clang_dir, "bin", "clang++"),
                ar=os.path.join(clang_dir, "bin", "llvm-ar"),
            )
        )

    cargo_dir = ensure_dir(os.path.join(staging_dir, ".cargo"))
    with open(os.path.join(cargo_dir, "config"), "w") as file:
        file.write(
            CARGO_CONFIG.format(
                target=target,
                linker=os.path.join(clang_dir, "bin", "clang"),
                ar=os.path.join(clang_dir, "bin", "llvm-ar"),
                sysroot=sysroot,
                shared_libs_root=shared_libs_root,
            )
        )

    cflags_key = "CFLAGS_%s-fuchsia" % target
    cflags_val = "--target=%s-fuchsia --sysroot=%s" % (target, sysroot)

    env = {
        "CARGO_HOME": cargo_dir,
        cflags_key: cflags_val,
        "PATH": os.environ["PATH"],
        "RUST_BACKTRACE": "1",
    }

    def run_build_command(command):
        command_args = [
            os.path.join(rust_root, "x.py"),
        ]
        command_args += command
        command_args += [
            "--config",
            config_file,
            "--src",
            rust_root,
        ]
        if debug:
            command_args.append("--verbose")
        print("Running: %s" % " ".join(command_args))
        # The builds need to run from a subdirectory of the staging dir
        # otherwise the cargo config set up above will get clobbered by x.py.
        out_dir = ensure_dir(os.path.join(staging_dir, "out"))
        subprocess.check_call(command_args, env=env, cwd=out_dir)

    run_build_command(["install"])

    print("The toolchain is ready at: %s" % toolchain_dir)


if __name__ == "__main__":
    main()
