# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Build graph dependency creation service.

This service handles the creation of the portage build dependency graphs and the
graphs mapping from portage packages to the dependency source.
"""

from chromite.api import api_config
from chromite.api import faux
from chromite.api import validate
from chromite.api.controller import controller_util
from chromite.api.gen.chromite.api import depgraph_pb2

# TODO(crbug/1081828): stop using build_target and drop it from the proto.
from chromite.lib import build_target_lib
from chromite.lib.parser import package_info
from chromite.service import dependency


def AugmentDepGraphProtoFromJsonMap(json_map, graph):
    """Augment package deps from |json_map| to graph object.

    Args:
        json_map: the json object that stores the portage package. This is
            generated from chromite.lib.service.dependency.GetBuildDependency()
        graph: the proto object that represents the dependency graph (see
            DepGraph message in chromite/api/depgraph.proto)
    """
    graph.sysroot.build_target.name = json_map["target_board"]
    graph.sysroot.path = json_map["sysroot_path"]
    # TODO(crbug/1081828): Drop this when no longer used.
    graph.build_target.name = json_map["target_board"]

    for data in json_map["package_deps"].values():
        package_dep_info = graph.package_deps.add()
        package_info_msg = package_dep_info.package_info
        package_info_msg.package_name = data["name"]
        package_info_msg.category = data["category"]
        package_info_msg.version = data["version"]
        for dep in data["deps"]:
            cpv = package_info.parse(dep)
            dep_package = package_dep_info.dependency_packages.add()
            controller_util.serialize_package_info(cpv, dep_package)

        package_CPV = controller_util.PackageInfoToString(package_info_msg)
        for path in json_map["source_path_mapping"][package_CPV]:
            source_path = package_dep_info.dependency_source_paths.add()
            source_path.path = path


def _GetBuildDependencyGraphResponse(_input_proto, output_proto, _config):
    """Add fake dep_graph data to a successful response."""
    output_proto.dep_graph.build_target.name = "target_board"


@faux.success(_GetBuildDependencyGraphResponse)
@faux.empty_error
@validate.require_each("packages", ["category", "package_name"])
@validate.validation_complete
def GetBuildDependencyGraph(
    input_proto: depgraph_pb2.GetBuildDependencyGraphRequest,
    output_proto: depgraph_pb2.GetBuildDependencyGraphResponse,
    _config: api_config.ApiConfig,
) -> None:
    """Create the build dependency graph.

    Args:
        input_proto: The input arguments message.
        output_proto: The empty output message.
        _config: The API call config.
    """
    if input_proto.HasField("sysroot"):
        board = input_proto.sysroot.build_target.name
        sysroot_path = input_proto.sysroot.path
    else:
        # TODO(crbug/1081828): stop using build_target & drop it from the proto.
        board = input_proto.build_target.name
        sysroot_path = build_target_lib.get_default_sysroot_path(board or None)

    packages = tuple(
        controller_util.PackageInfoToCPV(x) for x in input_proto.packages
    )

    json_map, sdk_json_map = dependency.GetBuildDependency(
        sysroot_path, board, packages
    )
    AugmentDepGraphProtoFromJsonMap(json_map, output_proto.dep_graph)
    AugmentDepGraphProtoFromJsonMap(sdk_json_map, output_proto.sdk_dep_graph)


def _ListResponse(_input_proto, output_proto, _config):
    """Add fake dependency data to a successful response."""
    package_dep = output_proto.package_deps.add()
    package_dep.category = "category"
    package_dep.package_name = "name"


@faux.success(_ListResponse)
@faux.empty_error
@validate.require("sysroot.build_target.name")
@validate.exists("sysroot.path")
@validate.require_each("src_paths", ["path"])
@validate.require_each("packages", ["category", "package_name"])
@validate.validation_complete
def List(
    input_proto: depgraph_pb2.ListRequest,
    output_proto: depgraph_pb2.ListResponse,
    _config: api_config.ApiConfig,
):
    """Get a list of package dependencies.

    Args:
        input_proto: The input arguments message.
        output_proto: The empty output message.
        _config: The API call config.
    """
    sysroot_path = input_proto.sysroot.path
    src_paths = [src_path.path for src_path in input_proto.src_paths]
    package_deps = dependency.GetDependencies(
        sysroot_path,
        src_paths=src_paths,
        packages=[
            controller_util.deserialize_package_info(package)
            for package in input_proto.packages
        ],
        include_rev_dependencies=input_proto.include_rev_deps,
    )
    for package in package_deps:
        pkg_info_msg = output_proto.package_deps.add()
        controller_util.serialize_package_info(package, pkg_info_msg)


def _StubGetToolchainPathsResponse(_input_proto, output_proto, _config):
    """Create a fake successful response for GetToolchainPaths."""
    stub_entry = output_proto.paths.add()
    stub_entry.path = "src/third_party/stub-package"


@faux.success(_StubGetToolchainPathsResponse)
@faux.empty_error
@validate.validation_complete
def GetToolchainPaths(_input_proto, output_proto, _config):
    """Get a list of paths that affect the toolchain."""
    toolchain_paths = dependency.DetermineToolchainSourcePaths()
    for p in toolchain_paths:
        source_path = output_proto.paths.add()
        source_path.path = p
