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

"""Script to check if the package(s) have prebuilts.

The script must be run inside the chroot. The output is a json dict mapping the
package atoms to a boolean for whether a prebuilt exists.
"""

import json
import logging
import os

from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib.parser import package_info


if cros_build_lib.IsInsideChroot():
    from chromite.lib import depgraph


def GetParser():
    """Build the argument parser."""
    parser = commandline.ArgumentParser(description=__doc__)

    parser.add_argument(
        "-b",
        "--build-target",
        dest="build_target_name",
        help="The build target that is being checked.",
    )
    parser.add_argument(
        "--output",
        type="str_path",
        required=True,
        help="The file path where the result json should be stored.",
    )
    parser.add_argument(
        "packages", nargs="+", help="The package atoms that are being checked."
    )

    return parser


def _ParseArguments(argv):
    """Parse and validate arguments."""
    parser = GetParser()
    opts = parser.parse_args(argv)

    if not os.path.exists(os.path.dirname(opts.output)):
        parser.error("Path containing the output file does not exist.")

    # Manually parse the packages as CPVs.
    packages = []
    for pkg in opts.packages:
        cpv = package_info.parse(pkg)
        if not cpv.atom:
            parser.error("Invalid package atom: %s" % pkg)

        packages.append(cpv)
    opts.packages = packages

    opts.Freeze()
    return opts


def main(argv) -> None:
    opts = _ParseArguments(argv)
    cros_build_lib.AssertInsideChroot()

    board = opts.build_target_name

    portage_binhost = portage_util.PortageqEnvvar("PORTAGE_BINHOST", board)
    logging.info("PORTAGE_BINHOST: %s", portage_binhost)

    results = {}
    bests = {}
    for cpv in opts.packages:
        query = cpv.cpvr or cpv.atom
        try:
            bests[query] = portage_util.PortageqBestVisible(query, board=board)
            logging.debug("Resolved %s best visible to %s", query, bests[query])
        except portage_util.NoVisiblePackageError:
            results[query] = False

    if bests:
        args = [
            # Fetch remote binpkg databases.
            "--getbinpkg",
            # Update packages to the latest version (we want updates to
            # invalidate installed packages).
            "--update",
            # Consider full tree rather than just immediate deps (changes in
            # dependencies and transitive deps can invalidate a binpkg).
            "--deep",
            # Packages with changed USE flags should be considered (changes in
            # dependencies and transitive deps can invalidate a binpkg).
            "--newuse",
            # Simplifies output.
            "--quiet",
            # Don't actually install it :).
            "--pretend",
            "--selective=n",
            # We run build_packages by default with these flags which can
            # trigger rebuilds (and ignoring of binpkgs) in more cases.
            "--newrepo",
            "--with-test-deps=y",
        ]
        if board:
            args.append("--board=%s" % board)
        args.extend("=%s" % best.cpvr for best in bests.values())

        generator = depgraph.DepGraphGenerator()
        logging.debug(
            "Initializing depgraph with: %s", cros_build_lib.CmdToStr(args)
        )
        generator.Initialize(args)

        for atom, best in bests.items():
            results[atom] = generator.HasPrebuilt(best.cpvr)

    osutils.WriteFile(opts.output, json.dumps(results))
