# 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 os
import sys
import subprocess

ROOT_PATH = os.environ["FUCHSIA_DIR"]
FX_PATH = os.path.join(ROOT_PATH, "scripts", "fx")

def _walk_up_path(path):
    res = set([path])
    while True:
        path, basename = os.path.split(path)
        if not path:
            break
        res.add(path)
    return res

def _find_cargo_target(path, target_filter=None):
    match_paths = _walk_up_path(path)
    all_targets = subprocess.check_output([FX_PATH, "build", "-t", "targets"])
    for gn_target in all_targets.split("\n"):
        target_parts = gn_target.split(":")
        if len(target_parts) < 2:
            continue
        target_path, gn_target = target_parts[0], target_parts[1]
        if target_path in match_paths and gn_target.endswith("_cargo"):
            gn_target=gn_target[:gn_target.rindex("_")]
            if target_filter and target_filter != gn_target:
                continue
            yield "{path}:{target}".format(
                    path=target_path,
                    target=gn_target,
            )

class GnTarget:
    def __init__(self, gn_target):
        gn_target = gn_target.lstrip("/")
        gn_target_parts = gn_target.split(":", 1)

        if gn_target_parts[0] == ".":
            cwd_rel_path = os.path.relpath(os.path.abspath("."), ROOT_PATH)
            target_filter = None if len(gn_target_parts) == 1 else gn_target_parts[1]
            gn_targets = list(_find_cargo_target(cwd_rel_path, target_filter))
            if not gn_targets:
                print "No cargo targets found at '{}'".format(cwd_rel_path)
                raise ValueError(gn_target)
            elif len(gn_targets) > 1:
                print "Multiple cargo targets found at '{}'".format(cwd_rel_path)
                for gn_target in gn_targets:
                    print "- {}".format(gn_target)
                raise ValueError(gn_target)
            else:
                gn_target, = gn_targets
                gn_target_parts = gn_target.split(":", 1)

        self.gn_target = gn_target
        self.parts = gn_target_parts

    def __str__(self):
        return self.gn_target

    @property
    def path(self):
        return os.path.join(ROOT_PATH, self.parts[0])

    def manifest_path(self, build_dir=None, prefer_host=False):
        if build_dir is None:
            build_dir = os.environ["FUCHSIA_BUILD_DIR"]

        if len(self.parts) == 1:
            # Turn foo/bar into foo/bar/bar
            path = os.path.join(self.gn_target, os.path.basename(self.gn_target))
        else:
            # Turn foo/bar:baz into foo/bar/baz
            path = self.gn_target.replace(":", os.sep)

        manifest_path_prefix = os.path.join(ROOT_PATH, build_dir)
        manifest_path_suffix = os.path.join("gen", path, "Cargo.toml")

        # By default, return the Fuchsia target Cargo.toml.
        # Fall back to the
        target_manifest_path = os.path.join(manifest_path_prefix, manifest_path_suffix)
        host_manifest_path = os.path.join(manifest_path_prefix, "host_x64", manifest_path_suffix)
        if not os.path.isfile(target_manifest_path) or prefer_host:
            return host_manifest_path
        else:
            return target_manifest_path

