#!/usr/bin/env python3.8
#
# Copyright 2020 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 os
import argparse
import hashlib
import shutil
import re
import sys
import json
import datetime

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

CARGO_PACKAGE_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.

# source GN: %(target)s"

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

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

CARGO_PACKAGE_DEP = """\
[dependencies.%(crate_name)s]
version = "0.0.1"
path = "%(crate_path)s"

"""


def strip_toolchain(target):
    return re.search("[^(]*", target)[0]


def lookup_gn_pkg_name(project, target):
    metadata = project.targets[target]
    return metadata["output_name"]


def rebase_gn_path(root_path, location, directory=False):
    assert location[0:2] == "//"
    # remove the prefix //
    path = location[2:]
    target = os.path.dirname(path) if directory else path
    return os.path.join(root_path, target)


class FeatureSpec(object):

    def __init__(self, features, default_features):
        self.features = features
        self.default_features = default_features


class Project(object):

    def __init__(self, project_json):
        self.targets = project_json
        self.patches = None
        self.third_party_features = {}

    def rust_targets(self):
        for target in self.targets.keys():
            if "crate_root" in self.targets[target]:
                yield target

    def dereference_group(self, target):
        """Dereference proc macro shims.

        If the target happens to be a group which just redirects you to a
        different target, returns the real target label. Otherwise, returns
        target.
        """
        meta = self.targets[target]
        if meta["type"] == "group":
            if len(meta["deps"]) == 1:
                dep = meta["deps"][0]
                dep_meta = self.targets[dep]
                return dep
        return target

    def expand_source_set(self, target):
        """Returns a list of dependencies if the target is a source_set.

        Returns dependencies as a list of strings if the target is a
        source_set, or None otherwise.
        """
        meta = self.targets[target]
        if meta["type"] == "source_set":
            return meta["deps"]


def write_toml_file(
        fout, metadata, project, target, lookup, root_path, root_build_dir):
    rust_crates_path = os.path.join(root_path, "third_party/rust_crates")

    edition = "2018" if "--edition=2018" in metadata["rustflags"] else "2015"

    if metadata["type"] in ["rust_library", "rust_proc_macro",
                            "static_library"]:
        target_type = "[lib]"
    else:
        if "--test" in metadata["rustflags"]:
            target_type = "[[test]]"
        else:
            target_type = "[[bin]]"

    if metadata["type"] == "rust_proc_macro":
        is_proc_macro = "proc-macro = true"
    else:
        is_proc_macro = ""

    features = []
    feature_pat = re.compile(r"--cfg=feature=\"(.*)\"$")
    for flag in metadata["rustflags"]:
        match = feature_pat.match(flag)
        if match:
            features.append(match.group(1))

    crate_type = "rlib"
    package_name = lookup_gn_pkg_name(project, target)

    fout.write(
        CARGO_PACKAGE_CONTENTS % {
            "target": target,
            "package_name": package_name,
            "crate_name": metadata["crate_name"],
            "version": "0.0.1",
            "year": datetime.datetime.now().year,
            "bin_or_lib": target_type,
            "is_proc_macro": is_proc_macro,
            "lib_crate_type": crate_type,
            "edition": edition,
            "source_root": rebase_gn_path(root_path, metadata["crate_root"]),
            "crate_name": metadata["crate_name"],
            "rust_crates_path": rust_crates_path,
        })

    if features:
        fout.write("\n[features]\n")
        # Filter 'default' feature out to avoid generating a duplicated entry.
        features = list(filter(lambda x: x != "default", features))
        fout.write("default = %s\n" % json.dumps(features))
        for feature in features:
            fout.write("%s = []\n" % feature)

    fout.write("\n[patch.crates-io]\n")
    for patch in project.patches:
        path = project.patches[patch]["path"]
        fout.write(
            "%s = { path = \"%s/%s\" }\n" % (patch, rust_crates_path, path))
    fout.write("\n")

    # collect all dependencies
    deps = metadata["deps"]
    while deps:
        dep = deps.pop()
        # handle proc macro shims:
        dep = project.dereference_group(dep)

        # If a dependency points to a source set, expand it into a list
        # of its deps, and append them to the deps list. Finally, continue
        # to the next item, since a source set itself is not considered a
        # dependency for our purposes.
        expanded_deps = project.expand_source_set(dep)
        if expanded_deps:
            deps.extend(expanded_deps)
            continue

        # this is a third-party dependency
        # TODO remove this when all things use GN. temporary hack?
        if "third_party/rust_crates:" in dep:
            has_third_party_deps = True
            match = re.search("rust_crates:([\w-]*)", dep)
            crate_name, version = str(match.group(1)).rsplit("-v", 1)
            version = version.replace("_", ".")
            feature_spec = project.third_party_features.get(crate_name)
            fout.write("[dependencies.\"%s\"]\n" % crate_name)
            fout.write("version = \"%s\"\n" % version)
            if feature_spec:
                fout.write(
                    "features = %s\n" % json.dumps(feature_spec.features))
                if feature_spec.default_features is False:
                    fout.write("default-features = false\n")
        # this is a in-tree rust target
        elif "crate_name" in project.targets[dep]:
            crate_name = lookup_gn_pkg_name(project, dep)
            output_name = project.targets[dep]["crate_name"]
            dep_dir = os.path.join(root_build_dir, "cargo", str(lookup[dep]))
            fout.write(
                CARGO_PACKAGE_DEP % {
                    "crate_path": dep_dir,
                    "crate_name": crate_name,
                })


def main():
    # TODO(tmandry): Remove all hardcoded paths and replace with args.
    parser = argparse.ArgumentParser()
    parser.add_argument("--root_build_dir", required=True)
    parser.add_argument("--fuchsia_dir", required=True)
    parser.add_argument("json_path")
    args = parser.parse_args()
    json_path = args.json_path

    project = None
    try:
        with open(json_path, "r") as json_file:
            project = json.loads(json_file.read())
    except IOError:
        print("Failed to generate Cargo.toml files")
        print("No project.json in the root of your out directory!")
        print("Run gn with the --ide=json flag set")
        # returns 0 so that CQ doesn't fail if this isn't set properly
        return 0

    project = Project(project)
    root_path = os.path.abspath(args.fuchsia_dir)
    root_build_dir = os.path.abspath(args.root_build_dir)

    rust_crates_path = os.path.join(root_path, "third_party/rust_crates")

    # this will be removed eventually?
    with open(rust_crates_path + "/Cargo.toml", "r") as f:
        cargo_toml = toml.load(f)
    project.patches = cargo_toml["patch"]["crates-io"]

    # Map from crate name to FeatureSpec. We don't include the version because we don't directly
    # depend on more than one version of the same crate.
    def collect_features(deps):
        for dep, info in deps.items():
            if isinstance(info, str):
                continue
            project.third_party_features[dep] = FeatureSpec(
                info.get("features", []), info.get("default-features", True))

    collect_features(cargo_toml["dependencies"])
    for target_info in cargo_toml["target"].values():
        collect_features(target_info.get("dependencies", {}))

    host_binaries = []
    target_binaries = []

    lookup = {}
    for idx, target in enumerate(project.rust_targets()):
        # hash is the GN target name without the prefixed //
        lookup[target] = hashlib.sha1(target[2:].encode("utf-8")).hexdigest()

    # remove the priorly generated rust crates
    gn_cargo_dir = os.path.join(root_build_dir, "cargo")
    shutil.rmtree(gn_cargo_dir, ignore_errors=True)
    os.makedirs(gn_cargo_dir)
    # Write a stamp file with a predictable name so the build system knows the
    # step ran successfully.
    with open(os.path.join(gn_cargo_dir, "generate_cargo.stamp"), "w") as f:
        f.truncate()

    for target in project.rust_targets():
        cargo_toml_dir = os.path.join(gn_cargo_dir, str(lookup[target]))
        try:
            os.makedirs(cargo_toml_dir)
        except OSError:
            print("Failed to create directory for Cargo: %s" % cargo_toml_dir)

        metadata = project.targets[target]
        with open(os.path.join(cargo_toml_dir, "Cargo.toml"), "w") as fout:
            write_toml_file(
                fout, metadata, project, target, lookup, root_path,
                root_build_dir)
    return 0


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