#!/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

TERM_COLOR_RED = '\033[91m'
TERM_COLOR_END = '\033[0m'

# Updates the path of the main target in the depfile to the relative path
# from base_path build_output_path
def fix_depfile(depfile_path, base_path, build_output_path):
    with open(depfile_path, "r") as depfile:
        content = depfile.read()
    content_split = content.split(': ', 1)
    target_path = os.path.relpath(build_output_path, start=base_path)
    new_content = "%s: %s" % (target_path, content_split[1])
    with open(depfile_path, "w") as depfile:
        depfile.write(new_content)

# 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

# Starts the given command and returns the newly created job.
def start_command(args, env):
    return subprocess.Popen(args, env=env, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)

def main():
    parser = argparse.ArgumentParser("Compiles a Rust crate")
    parser.add_argument("--rustc",
                        help="Path to rustc",
                        required=True)
    parser.add_argument("--cipd-version",
                        help="CIPD version of Rust toolchain",
                        required=False)
    parser.add_argument("--crate-root",
                        help="Path to source directory",
                        required=True)
    parser.add_argument("--cargo-toml-dir",
                        help="Path to directory in which a Cargo.toml for this target may be generated",
                        required=True)
    parser.add_argument("--crate-type",
                        help="Type of crate to build",
                        required=True,
                        choices=["bin", "rlib", "staticlib", "proc-macro"])
    parser.add_argument("--package-name",
                        help="Name of package to build",
                        required=True)
    parser.add_argument("--crate-name",
                        help="Name of crate to build",
                        required=True)
    parser.add_argument("--version",
                        help="Semver version of the crate being built",
                        required=True)
    parser.add_argument("--edition",
                        help="Edition of rust to use when compiling the crate",
                        required=True,
                        choices=["2015", "2018"])
    parser.add_argument("--opt-level",
                        help="Optimization level",
                        required=True,
                        choices=["0", "1", "2", "3", "s", "z"])
    parser.add_argument("--lto",
                        help="Use LTO",
                        required=False,
                        choices=["thin", "fat"])
    parser.add_argument("--output-file",
                        help="Path at which the output file should be stored",
                        required=True)
    parser.add_argument("--depfile",
                        help="Path at which the output depfile should be stored",
                        required=True)
    parser.add_argument("--root-out-dir",
                        help="Root output dir on which depfile paths should be rebased",
                        required=True)
    parser.add_argument("--test-output-file",
                        help="Path at which the unit test output file should be stored if --with-unit-tests is supplied",
                        required=False)
    parser.add_argument("--with-unit-tests",
                        help="Whether or not to build unit tests",
                        action="store_true",
                        required=False)
    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("--sysroot",
                        help="Path to the sysroot",
                        required=True)
    parser.add_argument("--shared-libs-root",
                        help="Path to the location of shared libraries",
                        required=True)
    parser.add_argument("--first-party-crate-root",
                        help="Path to directory containing the libs for first-party dependencies",
                        required=True)
    parser.add_argument("--third-party-deps-data",
                        help="Path to output of third_party_crates.py",
                        required=True)
    parser.add_argument("--out-info",
                        help="Path metadata output",
                        required=True)
    parser.add_argument("--dep-data",
                        action="append",
                        help="Path to metadata from a crate dependency",
                        required=False)
    parser.add_argument("--mmacosx-version-min",
                        help="Select macosx framework version",
                        required=False)
    parser.add_argument("--symbol-level",
                        help="Symbols to include (0=none, 1=minimal, 2=full)",
                        choices=["0", "1", "2"],
                        required=True)
    parser.add_argument("--warnings",
                        help="Whether or not to error on warnings (deny=error, allow=ignore)",
                        choices=["deny", "allow"],
                        required=True)

    parser.add_argument
    args = parser.parse_args()

    env = os.environ.copy()
    env["CC"] = os.path.join(args.clang_prefix, "clang")
    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")
    if args.cmake_dir:
        env["PATH"] = "%s:%s" % (env["PATH"], args.cmake_dir)
    env["RUST_BACKTRACE"] = "1"

    create_base_directory(args.output_file)

    if args.warnings == "allow":
        warnings_flag = "-Awarnings"
    else:
        warnings_flag = "-Dwarnings"

    call_args = [
        args.rustc,
        args.crate_root,
        warnings_flag,
        "--edition=%s" % args.edition,
        "--crate-type=%s" % args.crate_type,
        "--crate-name=%s" % args.crate_name,
        "--target=%s" % args.target,
        "-Copt-level=%s" % args.opt_level,
        "-Cdebuginfo=%s" % args.symbol_level,
        "-Lnative=%s" % args.shared_libs_root,
        "--color=always",
    ]

    if args.target.endswith("fuchsia"):
        call_args += [
            "-L", os.path.join(args.sysroot, "lib"),
            "-Clink-arg=--pack-dyn-relocs=relr",
            "-Clink-arg=--sysroot=%s" % args.sysroot,
            "-Clink-arg=-L%s" % os.path.join(args.sysroot, "lib"),
            "-Clink-arg=-L%s" % os.path.join(args.clang_resource_dir, args.target, "lib"),
            "-Clink-arg=--threads",
            "-Clink-arg=-dynamic-linker=ld.so.1",
        ]
        if args.target.startswith("aarch64"):
            call_args += ["-Clink-arg=--fix-cortex-a53-843419"]
    else:
        call_args += [
            "-Clinker=%s" % os.path.join(args.clang_prefix, "clang"),
        ]
        if args.target.startswith("aarch64"):
            call_args += ["-Clink-arg=-Wl,--fix-cortex-a53-843419"]
        if args.target.endswith("linux-gnu"):
            call_args += ["-Clink-arg=-Wl,--build-id"]
        if not args.target.endswith("darwin"):
            call_args += ["-Clink-arg=-Wl,--threads"]

    if args.mmacosx_version_min:
        call_args += [
            "-Clink-arg=-mmacosx-version-min=%s" % args.mmacosx_version_min,
        ]

    if args.lto:
        call_args += ["-Clto=%s" % args.lto]

    third_party_json = json.load(open(args.third_party_deps_data))
    search_paths = third_party_json["deps_folders"] + [ args.first_party_crate_root ]
    for path in search_paths:
        call_args += ["-L", "dependency=%s" % path]

    externs = []

    # Collect externs
    if args.dep_data:
        for data_path in args.dep_data:
            if not os.path.isfile(data_path):
                print TERM_COLOR_RED
                print "Missing Rust target data for dependency " + data_path
                print "Did you accidentally depend on a non-Rust target?"
                print TERM_COLOR_END
                return -1
            dep_data = json.load(open(data_path))
            if dep_data["third_party"]:
                package_name = dep_data["package_name"]
                crate_data = third_party_json["crates"][package_name]
                crate = crate_data["crate_name"]
                lib_path = crate_data["lib_path"]
            else:
                crate = dep_data["crate_name"]
                lib_path = dep_data["lib_path"]
            crate_underscore = crate.replace("-", "_")
            externs.append("%s=%s" % (crate_underscore, lib_path))

    # add externs to arguments
    for extern in externs:
        call_args += ["--extern", extern]

    # Build the depfile
    depfile_args = call_args + [
        "-o%s" % args.depfile,
        "--emit=dep-info",
    ]
    if args.with_unit_tests:
        depfile_args += ["--test"]
    depfile_job = start_command(depfile_args, env)

    # Build the desired output
    build_args = call_args + ["-o%s" % args.output_file]
    build_job = start_command(build_args, env)

    # Build the test harness
    if args.with_unit_tests:
        build_test_args = call_args + [
            "-o%s" % args.test_output_file,
            "--test",
        ]
        test_job = start_command(build_test_args, env)

    # Write output dependency info
    create_base_directory(args.out_info)
    with open(args.out_info, "w") as file:
        file.write(json.dumps({
            "crate_name": args.crate_name,
            "package_name": args.package_name,
            "third_party": False,
            "cargo_toml_dir": args.cargo_toml_dir,
            "lib_path": args.output_file,
            "version": args.version,
        }, sort_keys=True, indent=4, separators=(",", ": ")))

    # Wait for build jobs to complete

    stdout, stderr = depfile_job.communicate()
    if depfile_job.returncode != 0:
        print(stdout + stderr)
        return depfile_job.returncode
    fix_depfile(args.depfile, os.getcwd(), args.output_file)

    stdout, stderr = build_job.communicate()
    if build_job.returncode != 0:
        print(stdout + stderr)
        return build_job.returncode

    if args.with_unit_tests:
        stdout, stderr = test_job.communicate()
        if test_job.returncode != 0:
            print(stdout + stderr)
            return test_job.returncode

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