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

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

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

# List of packages that are part of the third-party build
# that live in-tree. In order to unify the two packages in builds
# that use the output cargo.tomls, we use `= "*"` as the version
# for these libraries, causing them to resolve via the patch section.
IN_TREE_THIRD_PARTY_PACKAGES = []

# semver regular expression, as suggested in http://semver.org
SEMVER_RE = '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'

CARGO_TOML_CONTENTS = '''\
# Copyright %(year)s 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.

[package]
name = "%(package_name)s"
version = "%(version)s"
edition = "%(edition)s"
license-file = "LICENSE"
authors = ["rust-fuchsia@fuchsia.com"]
description = "Rust crate for Fuchsia OS"
repository = "https://fuchsia.googlesource.com"

%(bin_or_lib)s
%(is_proc_macro)s
name = "%(crate_name)s"%(lib_crate_type)s
path = "%(source_root)s"

[features]
default = [%(features_array_items)s]

%(features_no_deps)s
'''


# Returns the package name and Cargo.toml dependency data for a dependency,
# or `None` on failure.
def add_dep(args, third_party_json, data_path):
    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 None
    dep_data = json.load(open(data_path))
    if dep_data["third_party"]:
        package_name = dep_data["package_name"]
        if package_name not in third_party_json["crates"]:
            print(TERM_COLOR_RED)
            print("Missing Rust target dependency:" + data_path)
            print(
                "Package is present in the third_party/ but is absent"
                " from dependency data: " + args.third_party_deps_data)
            print(
                "Maybe this package is conditionally disabled for the"
                " current configuration of '%s'?" % args.crate_name)
            print(TERM_COLOR_END)
            return None
        crate_data = third_party_json["crates"][package_name]
        data = crate_data["cargo_dependency_toml"]
    else:
        package_name = dep_data["package_name"]
        if package_name in IN_TREE_THIRD_PARTY_PACKAGES:
            data = {"version": "*"}
        else:
            data = {
                "path": dep_data["cargo_toml_dir"],
                "version": dep_data["version"],
            }
    return (package_name, data)


def cur_year():
    return datetime.datetime.now().year


def main():
    parser = argparse.ArgumentParser("Writes a Cargo.toml for a Rust crate")
    parser.add_argument(
        "--package-name", help="Name of the package", required=True)
    parser.add_argument("--crate-name", help="Name of the crate", required=True)
    parser.add_argument(
        "--source-root",
        help="Root lib.rs or main.rs for the crate",
        required=True)
    parser.add_argument("--version", help="Version of crate", required=True)
    parser.add_argument(
        "--edition",
        help="Edition of rust to use when compiling the crate",
        required=True)
    parser.add_argument(
        "--out-dir",
        help="Path to directory where Cargo.toml should be written",
        required=True)
    parser.add_argument(
        "--crate-type",
        help="Type of crate to build",
        required=True,
        choices=["bin", "rlib", "staticlib", "proc-macro"])
    parser.add_argument(
        "--lto",
        help="Add lto options to crate",
        required=False,
        choices=["none", "thin", "fat"])
    parser.add_argument(
        "--third-party-deps-data",
        help="Path to output of third_party_crates.py",
        required=True)
    parser.add_argument(
        "--dep-data",
        action="append",
        help="Path to metadata from a previous invocation of this script",
        required=False)
    parser.add_argument(
        "--test-only-dep-data",
        action="append",
        help="Path to metadata for test-only dependencies",
        required=False)
    parser.add_argument(
        "--feature",
        help="Feature to enable",
        action="append",
        dest="features",
        required=False)

    parser.add_argument
    args = parser.parse_args()
    cargo_toml_path = os.path.join(args.out_dir, "Cargo.toml")

    if re.search(SEMVER_RE, args.version) is None:
        print(TERM_COLOR_RED)
        print(
            'Invalid semver version number "%s" for package %s' %
            (args.version, args.package_name))
        print(TERM_COLOR_END)
        return -1

    third_party_json = {"crates": {}, "patches": []}

    deps = {}
    if args.dep_data:
        for data_path in args.dep_data:
            data = add_dep(args, third_party_json, data_path)
            if data is None:
                return -1
            deps[data[0]] = data[1]
    test_only_deps = {}
    if args.test_only_dep_data:
        for data_path in args.test_only_dep_data:
            data = add_dep(args, third_party_json, data_path)
            if data is None:
                return -1
            test_only_deps[data[0]] = data[1]

    features = args.features or []

    with open(cargo_toml_path, "w") as file:
        file.write(
            CARGO_TOML_CONTENTS % {
                "package_name":
                    args.package_name,
                "crate_name":
                    args.crate_name,
                "version":
                    args.version,
                "edition":
                    args.edition,
                "year":
                    cur_year(),
                "bin_or_lib":
                    "[[bin]]" if args.crate_type == "bin" else "[lib]",
                "is_proc_macro":
                    "proc-macro = true"
                    if args.crate_type == "proc-macro" else "",
                "lib_crate_type":
                    "" if args.crate_type == "bin" else
                    ('\ncrate_type = ["%s"]' % args.crate_type),
                "source_root":
                    args.source_root,
                "features_array_items":
                    ", ".join(['"%s"' % f for f in features]),
                "features_no_deps":
                    "\n".join(["%s = []" % f for f in features]),
            })
        dependencies = {"dependencies": deps}
        file.write(
            pytoml.dumps(
                {
                    "dependencies": deps,
                    "dev-dependencies": test_only_deps,
                    "patch": {
                        "crates-io": third_party_json["patches"]
                    },
                }))

        profile = {"profile": {"release": {"panic": "abort", "opt-level": "z"}}}
        if args.lto and args.lto != "none":
            profile["profile"]["release"]["lto"] = args.lto

        file.write(pytoml.dumps(profile))


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