#!/usr/bin/env 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 json
import os
import subprocess
import sys

ROOT_PATH = os.path.abspath(__file__ + "/../../..")
sys.path += [os.path.join(ROOT_PATH, "third_party", "pytoml")]
import pytoml

# "foo" from "foo 0.1.0 (//path/to/crate)"
def package_name_from_crate_id(crate_id):
    return crate_id.split(" ")[0]

# Removes the (//path/to/crate) from the crate id "foo 0.1.0 (//path/to/crate)"
# This is necessary in order to support locally-patched (mirrored) crates
def pathless_crate_id(crate_id):
    split_id = crate_id.split(" ")
    return split_id[0] + " " + split_id[1]

# Creates the directory containing the given file.
def create_base_directory(file):
    path = os.path.dirname(file)
    try:
        os.makedirs(path)
    except os.error:
        # Already existed.
        pass

# Runs the given command and returns its return code and output.
def run_command(args, env, cwd):
    job = subprocess.Popen(args, env=env, cwd=cwd, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    stdout, stderr = job.communicate()
    return (job.returncode, stdout, stderr)

def main():
    parser = argparse.ArgumentParser("Compiles all third-party Rust crates")
    parser.add_argument("--rustc",
                        help="Path to rustc",
                        required=True)
    parser.add_argument("--cargo",
                        help="Path to the cargo tool",
                        required=True)
    parser.add_argument("--crate-root",
                        help="Path to the crate root",
                        required=True)
    parser.add_argument("--opt-level",
                        help="Optimization level",
                        required=True,
                        choices=["0", "1", "2", "3", "s", "z"])
    parser.add_argument("--symbol-level",
                        help="Symbols to include (0=none, 1=minimal, 2=full)",
                        choices=["0", "1", "2"],
                        required=True)
    parser.add_argument("--out-dir",
                        help="Path at which the output libraries should be stored",
                        required=True)
    parser.add_argument("--out-deps-data",
                        help="File in which data about the dependencies should be stored",
                        required=True)
    parser.add_argument("--target",
                        help="Target for which this crate is being compiled",
                        required=True)
    parser.add_argument("--cmake-dir",
                        help="Path to the directory containing cmake",
                        required=True)
    parser.add_argument("--clang_prefix",
                        help="Path to the clang prefix",
                        required=True)
    parser.add_argument("--clang-resource-dir",
                        help="Path to the clang resource dir",
                        required=True)
    parser.add_argument("--mmacosx-version-min",
                        help="Select macosx framework version",
                        required=False)
    # TODO(cramertj) make these args required when the third_party/rust_crates change lands
    parser.add_argument("--sysroot",
                        help="Path to the sysroot",
                        required=False)
    parser.add_argument("--lib-dir",
                        help="Path to the location of shared libraries",
                        action='append', default=[])
    parser.add_argument("--cipd-version",
                        help="CIPD version of Rust toolchain",
                        required=False)
    parser.add_argument
    args = parser.parse_args()

    env = os.environ.copy()
    create_base_directory(args.out_dir)

    clang_c_compiler = os.path.join(args.clang_prefix, "clang")

    rustflags = [
        "-Copt-level=" + args.opt_level,
        "-Cdebuginfo=" + args.symbol_level,
    ]

    if args.target.endswith("fuchsia"):
        if args.target.startswith("aarch64"):
            rustflags += ["-Clink-arg=--fix-cortex-a53-843419"]
        rustflags += [
            "-L", os.path.join(args.sysroot, "lib"),
            "-Clink-arg=--pack-dyn-relocs=relr",
            "-Clink-arg=--threads",
            "-Clink-arg=-L%s" % os.path.join(args.sysroot, "lib"),
            "-Clink-arg=-L%s" % os.path.join(args.clang_resource_dir, args.target, "lib"),
        ]
        if args.sysroot:
            rustflags.append("-Clink-arg=--sysroot=" + args.sysroot)
        for dir in args.lib_dir:
            rustflags.append("-Lnative=" + dir)
    else:
        if args.target.startswith("aarch64"):
            rustflags += ["-Clink-arg=-Wl,--fix-cortex-a53-843419"]
        if args.target.endswith("linux-gnu"):
            rustflags += ["-Clink-arg=-Wl,--build-id"]
        if not args.target.endswith("darwin"):
            rustflags += ["-Clink-arg=-Wl,--threads"]
        env["CARGO_TARGET_LINKER"] = clang_c_compiler
        env["CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER"] = clang_c_compiler
        env["CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER"] = clang_c_compiler
        env["CARGO_TARGET_%s_LINKER" % args.target.replace("-", "_").upper()] = clang_c_compiler
        rustflags += ["-Clink-arg=--target=" + args.target]

    if args.mmacosx_version_min:
        rustflags += ["-Clink-arg=-mmacosx-version-min=%s" % args.mmacosx_version_min]
    env["CARGO_TARGET_%s_RUSTFLAGS" % args.target.replace("-", "_").upper()] = (
        ' '.join(rustflags)
    )
    env["CARGO_TARGET_DIR"] = args.out_dir
    env["CARGO_BUILD_DEP_INFO_BASEDIR"] = args.out_dir
    env["RUSTC"] = args.rustc
    env["RUST_BACKTRACE"] = "1"
    env["CC"] = clang_c_compiler
    if args.sysroot:
        env["CFLAGS"] = " ".join(["--sysroot=" + args.sysroot] +
                                 ["-L" + dir for dir in args.lib_dir])
    env["CXX"] = os.path.join(args.clang_prefix, "clang++")
    env["AR"] = os.path.join(args.clang_prefix, "llvm-ar")
    env["RANLIB"] = os.path.join(args.clang_prefix, "llvm-ranlib")
    env["PATH"] = "%s:%s" % (env["PATH"], args.cmake_dir)

    call_args = [
        args.cargo,
        "build",
        "--color=always",
        "--target=%s" % args.target,
        "--frozen",
    ]

    call_args.append("--message-format=json")

    retcode, stdout, stderr = run_command(call_args, env, args.crate_root)
    if retcode != 0:
        # The output is not particularly useful as it is formatted in JSON.
        # Re-run the command with a user-friendly format instead.
        del call_args[-1]
        _, stdout, stderr = run_command(call_args, env, args.crate_root)
        print(stdout + stderr)
        return retcode

    cargo_toml_path = os.path.join(args.crate_root, "Cargo.toml")
    with open(cargo_toml_path, "r") as file:
        cargo_toml = pytoml.load(file)

    crate_id_to_info = {}
    deps_folders = set()
    for line in stdout.splitlines():
        data = json.loads(line)
        if "filenames" not in data:
            continue
        crate_id = pathless_crate_id(data["package_id"])
        assert len(data["filenames"]) == 1
        lib_path = data["filenames"][0]

        # For libraries built for both the host and the target, pick
        # the one being built for the target.
        # If we've already seen a lib with the given ID and the new one doesn't
        # contain our target, discard it and keep the current entry.
        if (crate_id in crate_id_to_info) and (args.target not in lib_path):
            continue

        crate_name = data["target"]["name"]

        # Build scripts built for our dependencies unfortunately have the same
        # package ID as the crates themselves. In order to distinguish them,
        # we look for the crate name that cargo uses for these artifacts,
        # "build-script-build".
        if crate_name == "build-script-build":
            continue

        if crate_name != "fuchsia-third-party":
            # go from e.g. target/debug/deps/libfoo.rlib to target/debug/deps
            deps_folders.add(os.path.dirname(lib_path))

        crate_id_to_info[crate_id] = {
            "crate_name": crate_name,
            "lib_path": lib_path,
        }

    cargo_lock_path = os.path.join(args.crate_root, "Cargo.lock")
    with open(cargo_lock_path, "r") as file:
        cargo_lock_toml = pytoml.load(file)

    # output the info for fuchsia-third-party's direct dependencies
    crates = {}
    cargo_dependencies = cargo_toml["dependencies"]
    fuchsia_target_spec = 'cfg(target_os = "fuchsia")'
    non_fuchsia_target_spec = 'cfg(not(target_os = "fuchsia"))'
    if "fuchsia" in args.target:
        target_spec = fuchsia_target_spec
        non_target_spec = non_fuchsia_target_spec
    else:
        target_spec = non_fuchsia_target_spec
        non_target_spec = fuchsia_target_spec
    target_only_deps = cargo_toml \
            .get("target", {}) \
            .get(target_spec, {}) \
            .get("dependencies", [])
    cargo_dependencies.update(target_only_deps)
    other_target_deps = cargo_toml \
            .get("target", {}) \
            .get(non_target_spec, {}) \
            .get("dependencies", [])
    for package in cargo_lock_toml["package"]:
        if package["name"] == "fuchsia-third-party":
            for crate_id in package["dependencies"]:
                crate_id = pathless_crate_id(crate_id)
                if crate_id in crate_id_to_info:
                    crate_info = crate_id_to_info[crate_id]
                    crate_name = crate_info["crate_name"]
                    package_name = package_name_from_crate_id(crate_id)
                    if package_name in cargo_dependencies:
                        crate_info["cargo_dependency_toml"] = cargo_dependencies[package_name]
                        crates[package_name] = crate_info
                    elif package_name not in other_target_deps:
                        print (package_name + " not found in Cargo.toml dependencies section")
                        return 1

    # normalize paths for patches
    patches = cargo_toml["patch"]["crates-io"]
    for patch in patches:
        path = patches[patch]["path"]
        path = os.path.join(args.crate_root, path)
        patches[patch] = { "path": path }

    create_base_directory(args.out_deps_data)
    with open(args.out_deps_data, "w") as file:
        file.write(json.dumps({
            "crates": crates,
            "deps_folders": list(deps_folders),
            "patches": patches,
        }, sort_keys=True, indent=4, separators=(",", ": "))) # for humans

if __name__ == '__main__':
    sys.exit(main())
