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

"""Library for validating ebuild license information, and generating credits.

Documentation on this script is also available here:
  https://dev.chromium.org/chromium-os/licensing
"""

import codecs
import fnmatch
import html
import json
import logging
import os
from pathlib import Path
import re
from typing import List, Optional

from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib.parser import package_info
from chromite.utils import gs_urls_util
from chromite.utils.parser import ebuild_license


# See https://crbug.com/207004 for discussion.
PER_PKG_LICENSE_DIR = portage_util.VDB_PATH

STOCK_LICENSE_DIRS = [
    "src/third_party/portage-stable/licenses",
]

# The SDK does not have generated overlay info in it, so hardcode these
# fallbacks for them.
SDK_OVERLAY_DIRS = [
    "src/third_party/chromiumos-overlay",
    "src/private-overlays/chromeos-overlay",
]

COPYRIGHT_ATTRIBUTION_DIR = os.path.join(
    constants.SOURCE_ROOT,
    "src/third_party/chromiumos-overlay/licenses/copyright-attribution",
)

# Virtual packages don't need to have a license and often don't, so we skip them
# chromeos-base contains google platform packages that are covered by the
# general license at top of tree, so we skip those too.
SKIPPED_CATEGORIES = [
    "virtual",
]

# If you have an early package for which license terms have yet to be decided,
# use this. It will cause licensing for the package to be mostly ignored.
# Tainted builds will fail signing with official keys.
TAINTED = "TAINTED"

# HTML outputs will include this tag if tainted.
TAINTED_COMMENT_TAG = "<!-- tainted -->"

SKIPPED_LICENSES = [
    # Some of our packages contain binary blobs for which we have special
    # negotiated licenses, and no need to display anything publicly. Strongly
    # consider using Google-TOS instead, if possible.
    "Proprietary-Binary",
]

LICENSE_BASENAMES_REGEX = [
    r"^copyright$",
    r"^copyright[.]txt$",
    r"^copyright[.]regex$",  # llvm
    r"^copying.*$",
    r"^licen[cs]e.*$",
    r"^licensing.*$",  # libatomic_ops
    r"^ipa_font_license_agreement_v1[.]0[.]txt$",  # ja-ipafonts
    r"^MIT-LICENSE$",  # rake
    r"^PKG-INFO$",  # copyright assignment for
    # some python packages
    # (netifaces, unittest2)
]

# Patterns to never classify as a license file. Unlike LICENSE_BASENAMES_REGEX,
# the patterns here are applied to the full path relative to the work dir root.
# Exclusions found this way are logged. We also skip `.git`, but don't log it.
LICENSE_PATHS_EXCLUDE_REGEX = (
    # We never want a GPL license when looking for copyright attribution, so we
    # skip things like license.gpl. Only check the basename.
    r"[^/]*GPL[^/]*$",
    # Skip files that are likely source code or object files generated from
    # source code. E.g., license.py, license.o, etc.
    r"\.py$",
    r"\.o$",
    # Haskell source and object files.
    r"\.hs$",
    r"\.hi$",
    r"\.dyn_hi$",
    r"\.dyn_o$",
    # This folder contains json files listing every license known to Cabal.
    r"Cabal/license-list-data",
)

# Any license listed here found in the ebuild will make the code look for
# license files inside the package source code in order to get copyright
# attribution from them.
COPYRIGHT_ATTRIBUTION_LICENSES = {
    "BSD",  # requires distribution of copyright notice
    "BSD-2",  # so does BSD-2 https://opensource.org/licenses/BSD-2-Clause
    "BSD-2-with-patent",
    "BSD-3",  # and BSD-3? https://opensource.org/licenses/BSD-3-Clause
    "BSD-4",  # and 4?
    "BSD-with-attribution",
    "BSD-with-disclosure",
    "ISC",  # so does ISC https://opensource.org/licenses/ISC
    "MIT",
    "MIT-with-advertising",
    "Old-MIT",
}

# The following licenses are not invalid or to show as a less helpful stock
# license, but it's better to look in the source code for a more specific
# license if there is one, but not an error if no better one is found.
# Note that you don't want to set just anything here since any license here
# will be included once in stock form and a second time in custom form if
# found (there is no good way to know that a license we found on disk is the
# better version of the stock version, so we show both).
LOOK_IN_SOURCE_LICENSES = [
    "PSF-2",  # The custom license in python is more complete than the template.
    # As far as I know, we have no requirement to do copyright attribution for
    # these licenses, but the license included in the code has slightly better
    # information than the stock Gentoo one (including copyright attribution).
    "BZIP2",  # Single use license, do copyright attribution.
    "OFL",  # Almost single use license, do copyright attribution.
    "OFL-1.1",  # Almost single use license, do copyright attribution.
    "UoI-NCSA",  # Only used by NSCA, might as well show their custom copyright.
]

# These are licenses we don't want to allow anyone to use.  Globs allowed.
#
# Gentoo normally uses a naming convention of <name> or <name>-<ver>.  We don't
# block AGPL* in the pathological case that an unrelated license comes up with
# the same first few letters.  Not likely, but not impossible.  But we do block
# AGPL-* as it's much more likely we'll get a newer version using the same base
# name which we want to be future proof against.
BAD_LICENSE_PATTERNS = {
    # Google policy to avoid these licenses (and all versions of them).
    # https://opensource.org/licenses/AGPL-3.0
    "AGPL",
    "AGPL-*",
    # Catch all versions & variants of CC-BY-NC, CC-BY-NC-ND, and CC-BY-NC-SA.
    # https://creativecommons.org/licenses/by-nc/3.0/
    "CC-BY-NC*",
    # https://opensource.org/licenses/CPAL-1.0
    "CPAL",
    "CPAL-*",
    # https://opensource.org/licenses/EUPL-1.2
    "EUPL",
    "EUPL-*",
    # https://en.wikipedia.org/wiki/WTFPL  nocheck
    "WTFPL*",  # nocheck
    # These aren't actual licenses :).
    "as-is",
}

# List of overlays that must use 'metapackage' license for virtual packages.
# Throw error for those, print a warning for others.
OVERLAYS_METAPACKAGES_MUST_USE_VIRTUAL = [
    "chromiumos-overlay",
    "chromeos-overlay",
    "chromeos-partner-overlay",
]

# The full names of packages which we want to generate license information for
# even though they have an empty installation size.
SIZE_EXEMPT_PACKAGES = [
    "net-print/fuji-xerox-printing-license",
    "net-print/fujifilm-printing-license",
    "net-print/konica-minolta-printing-license",
    "net-print/nec-printing-license",
    "net-print/xerox-printing-license",
]

# Find the directory of this script.
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))

# The template files we depend on for generating HTML.
TMPL = os.path.join(SCRIPT_DIR, "about_credits.tmpl")
ENTRY_TMPL = os.path.join(SCRIPT_DIR, "about_credits_entry.tmpl")
SHARED_LICENSE_TMPL = os.path.join(
    SCRIPT_DIR, "about_credits_shared_license_entry.tmpl"
)

# dir_set constants for _GetLicenseDirectories.
_CUSTOM_DIRS = "custom"
_STOCK_DIRS = "stock"
_BOTH_DIRS = "both"

# Banner shown when generating a placeholder credits.
_PLACEHOLDER_BANNER = """
<div style="border: dashed; margin: 1em; padding: 1em;">
<p style="font-weight: bold;">Placeholder Credits Page</p>
<p>
See <a href="https://dev.chromium.org/chromium-os/licensing/licensing-for-chromiumos-developers">Licensing for ChromiumOS Developers</a> and
<a href="https://dev.chromium.org/chromium-os/licensing/licensing-for-chromiumos-package-owners">Licensing for ChromiumOS Package Owners</a>
for more details on the credits system.
</p>
<p>
If you need to change styles, fonts, layout, etc of the
<a href="chrome://os-credits">chrome://os-credits</a> page, edit
<a href="https://chromium.googlesource.com/chromiumos/chromite/+/HEAD/licensing/about_credits.tmpl">chromite/licensing/about_credits.tmpl</a>.
The template is used to generate a device-dependent about_os_credits.html
when a CrOS image is built.
</p>
</div>
"""


def _convert_yaml_to_json(yaml_file: str, json_file: str) -> None:
    """Migrate old YAML format to JSON.

    We have a lot of existing binpkgs that used yaml, so keep this for a while.
    TODO(build): Make this fatal in Jan 2024.

    Args:
        yaml_file: Path to the old existing yaml file.
        json_file: Path to the json file to write.
    """
    # The yaml files are legacy, so we don't normally load the module, and
    # because it's not a common 3rd party install.
    import yaml  # pylint: disable=import-error

    class SaferLoader(yaml.SafeLoader):
        """Augment the yaml.SafeLoader with unicode and tuple types."""

        def construct_tuple(self, node):
            return tuple(self.construct_sequence(node))

        def construct_unicode(self, node):
            return node.value

    SaferLoader.add_constructor(
        "tag:yaml.org,2002:python/tuple", SaferLoader.construct_tuple
    )
    SaferLoader.add_constructor(
        "tag:yaml.org,2002:python/unicode", SaferLoader.construct_unicode
    )

    logging.debug("Migrating YAML (%s) to JSON (%s)", yaml_file, json_file)

    old_data = yaml.load(osutils.ReadFile(yaml_file), Loader=SaferLoader)
    data = {}
    for key, value in old_data:
        if isinstance(value, set):
            value = sorted(value)
        data[key] = value
    osutils.WriteFile(json_file, json.dumps(data), sudo=True)


# This is called directly by src/repohooks/pre-upload.py
def GetLicenseTypesFromEbuild(
    ebuild_contents, overlay_path, buildroot=constants.SOURCE_ROOT
):
    """Returns a list of license types from an ebuild.

    This function does not always return the correct list, but it is
    faster than using portageq for not having to access chroot. It is
    intended to be used for tasks such as presubmission checks.

    Args:
        ebuild_contents: contents of ebuild.
        overlay_path: path of the overlay containing the ebuild
        buildroot: base directory, usually constants.SOURCE_ROOT, useful for
            tests

    Returns:
        list of licenses read from ebuild.

    Raises:
        ValueError: ebuild errors.
    """
    ebuild_env_tmpl = """
has() { [[ " ${*:2} " == *" $1 "* ]]; }
inherit() {
  local overlay_list="%(overlay_list)s"
  local eclass overlay f
  for eclass; do
    has ${eclass} ${_INHERITED_} && continue
    _INHERITED_+=" ${eclass}"
    for overlay in %(overlay_list)s; do
      f="${overlay}/eclass/${eclass}.eclass"
      if [[ -e ${f} ]]; then
        source "${f}"
        break
      fi
     done
  done
}
%(ebuild)s"""

    repo_name = portage_util.GetOverlayName(overlay_path)
    overlays = portage_util.FindOverlays(
        constants.BOTH_OVERLAYS, repo_name, buildroot=buildroot
    )
    tmpl_env = {
        "ebuild": ebuild_contents,
        "overlay_list": " ".join(overlays),
    }

    with cros_build_lib.UnbufferedNamedTemporaryFile() as f:
        osutils.WriteFile(f.name, ebuild_env_tmpl % tmpl_env)
        env = osutils.SourceEnvironment(
            f.name, allowlist=["LICENSE"], ifs=" ", multiline=True
        )

    if not env.get("LICENSE"):
        raise ValueError("No LICENSE found in the ebuild.")
    if re.search(r"[,;]", env["LICENSE"]):
        raise ValueError(
            "LICENSE field in the ebuild should be whitespace-limited."
        )

    return env["LICENSE"].split()


class PackageLicenseError(Exception):
    """Thrown for failures while getting license information for a package.

    This will cause the processing to error in the end.
    """


class PackageCorrectnessError(Exception):
    """Thrown if a package has build info incompatible with the license.

    For example, thrown when a package with LICENSE=metapackage installs files.
    This will cause the processing to error in the end.
    """


class PackageInfo:
    """Package specific information, mostly about licenses."""

    def __init__(self, sysroot, fullnamerev) -> None:
        """Package info initializer.

        Args:
            sysroot: The board this package was built for.
            fullnamerev: package name of the form 'x11-base/X.Org-1.9.3-r23'

        Raises:
            ValueError if |fullnamerev| is not a valid package string.
        """

        self.sysroot = sysroot

        package = package_info.parse(fullnamerev)
        self.category = package.category
        self.name = package.package
        self.version = package.version
        self.revision = package.revision
        self.fullname = package.cp
        self.fullnamerev = package.cpvr

        if fullnamerev != self.fullnamerev:
            # Parsed package doesn't match original, invalid package passed.
            raise ValueError(
                "portage couldn't find %s, missing version number?"
                % fullnamerev
            )

        #
        # These fields hold license information used to generate the credits
        # page.
        #

        # This contains licenses names for this package.
        self.license_names = set()

        # Full Text of discovered license information.
        self.license_text_scanned = []

        self.homepages = []

        #
        # These fields show the results of processing.
        #

        # After reading basic package information, we can mark the package as
        # one to skip in licensing.
        self.skip = False

        # Intelligently populate initial skip information.
        self.LookForSkip()

        # Set to something by GetLicenses().
        self.tainted = None

        self.ebuild_path = None

    @property
    def license_dump_path(self):
        """e.g. /build/x86-alex/var/db/pkg/sys-apps/dtc-1.4.0/license.json.

        Only valid for packages that have already been emerged.
        """
        return os.path.join(
            self.sysroot, PER_PKG_LICENSE_DIR, self.fullnamerev, "license.json"
        )

    def _RunEbuildPhases(self, ebuild_path, phases):
        """Run a list of ebuild phases on an ebuild.

        Args:
            ebuild_path: exact path of the ebuild file.
            phases: list of phases like ['clean', 'fetch'] or ['unpack'].

        Returns:
            ebuild command output
        """
        ebuild_cmd = cros_build_lib.GetSysrootToolPath(self.sysroot, "ebuild")
        return cros_build_lib.run(
            [ebuild_cmd, ebuild_path] + phases, stdout=True, encoding="utf-8"
        )

    def _GetOverrideLicense(self):
        """Check COPYRIGHT_ATTRIBUTION_DIR for license w/ copyright attribution.

        For dev-util/bsdiff-4.3-r5, the code will look for
        dev-util/bsdiff-4.3-r5
        dev-util/bsdiff-4.3
        dev-util/bsdiff

        It is ok to have more than one bsdiff license file, and an empty file
        acts as a rubout (i.e. an empty dev-util/bsdiff-4.4 will shadow
        dev-util/bsdiff and tell the licensing code to look in the package
        source for a license instead of using dev-util/bsdiff as an override).

        Returns:
            False (no license found) or a multiline license string.
        """
        license_read = None
        # dev-util/bsdiff-4.3-r5 -> bsdiff-4.3-r5
        filename = os.path.basename(self.fullnamerev)
        license_path = os.path.join(
            COPYRIGHT_ATTRIBUTION_DIR, os.path.dirname(self.fullnamerev)
        )
        pv = package_info.parse(filename)
        for filename in (pv.pvr, pv.pv, pv.package):
            file_path = os.path.join(license_path, filename)
            logging.debug(
                "Looking for override copyright attribution license in %s",
                file_path,
            )
            if os.path.exists(file_path):
                # Turn
                # SRC_ROOT/CHROMIUMOS_OVERLAY_DIR/../dev-util/bsdiff
                # into
                # chromiumos-overlay/../dev-util/bsdiff
                short_dir_path = os.path.join(
                    *file_path.rsplit(os.path.sep, 5)[1:]
                )
                license_read = (
                    "Copyright Attribution License %s:\n\n" % short_dir_path
                )
                license_read += ReadUnknownEncodedFile(
                    file_path, "read copyright attribution license"
                )
                break

        return license_read

    def _ExtractLicenses(self, src_dir, need_copyright_attribution) -> None:
        """Scrounge for text licenses in the source of package we'll unpack.

        This is only called if we couldn't get usable licenses from the ebuild,
        or one of them is BSD/MIT like which forces us to look for a file with
        copyright attribution in the source code itself.

        First, we have a shortcut where we scan COPYRIGHT_ATTRIBUTION_DIR to see
        if we find a license for this package. If so, we use that.
        Typically, it'll be used if the unpacked source does not have the
        license that we're required to display for copyright attribution (in
        some cases it's plain absent, in other cases, it could be in a filename
        we don't look for).

        Otherwise, we scan the unpacked source code for what looks like license
        files as defined in LICENSE_BASENAMES_REGEX.

        Raises:
            AssertionError: on runtime errors
            PackageLicenseError: couldn't find copyright attribution file.
        """
        license_override = self._GetOverrideLicense()
        if license_override:
            self.license_text_scanned = [license_override]
            return

        if not src_dir:
            self.ebuild_path = self._FindEbuildPath()
            self._RunEbuildPhases(self.ebuild_path, ["clean", "fetch"])
            raw_output = self._RunEbuildPhases(self.ebuild_path, ["unpack"])
            output = raw_output.stdout.splitlines()
            # pylint: disable=line-too-long
            #
            # Output is spammy, it looks like this:
            #  * gc-7.2d.tar.gz RMD160 SHA1 SHA256 size ;-) ...                 [ ok ]
            #  * checking gc-7.2d.tar.gz ;-) ...                                [ ok ]
            #  * Running stacked hooks for pre_pkg_setup
            #  *    sysroot_build_bin_dir ...
            #  [ ok ]
            #  * Running stacked hooks for pre_src_unpack
            #  *    python_multilib_setup ...
            #  [ ok ]
            # >>> Unpacking source...
            # >>> Unpacking gc-7.2d.tar.gz to /build/x86-alex/tmp/po/[...]ps-7.2d/work
            # >>> Source unpacked in /build/x86-alex/tmp/portage/[...]ops-7.2d/work
            # So we only keep the last 2 lines, the others we don't care about.
            #
            # pylint: enable=line-too-long
            output = [
                line
                for line in output
                if line[0:3] == ">>>" and line != ">>> Unpacking source..."
            ]
            for line in output:
                logging.info(line)

            tmpdir = portage_util.PortageqEnvvar(
                "PORTAGE_TMPDIR", sysroot=self.sysroot
            )
            # tmpdir gets something like /build/daisy/tmp/
            src_dir = os.path.join(tmpdir, "portage", self.fullnamerev, "work")

            if not os.path.exists(src_dir):
                raise AssertionError(
                    "Unpack of %s didn't create %s. Version mismatch"
                    % (self.fullnamerev, src_dir)
                )

        # pylint: disable=line-too-long
        #
        # You may wonder how deep should we go?
        # In case of packages with sub-packages, it could be deep.
        # Let's just be safe and get everything we can find.
        # In the case of libatomic_ops, it's actually required to look deep
        # to find the MIT license:
        # dev-libs/libatomic_ops-7.2d/work/gc-7.2/libatomic_ops/doc/LICENSING.txt
        #
        # pylint: enable=line-too-long
        # Use "%P" to truncate results to look like this: swig-2.0.4/COPYRIGHT
        args = ["find", src_dir, "-type", "f", "-printf", "%P\\n"]
        result = cros_build_lib.run(args, stdout=True, encoding="utf-8")
        license_files = FilterLicenseFileCandidates(result.stdout)

        if not license_files:
            if need_copyright_attribution:
                google_bsd_msg = ""
                if need_copyright_attribution == {"BSD"}:
                    google_bsd_msg = """
If this source code was entirely authored by Google employees, you can instead
just change the ebuild settings like so:
  -LICENSE="BSD"
  +LICENSE="BSD-Google"\
"""
                logging.error(
                    """\
%s: unable to find usable license.
The ebuild says it uses at least %s which requires copyright attribution,
but there was no license file that this script could find in the package's
source distribution:
  %s

You will need to investigate that source directory to figure out which license
to assign.  Once you've found it, copy the entire license file to:
  %s
%s""",
                    self.fullnamerev,
                    need_copyright_attribution,
                    src_dir,
                    COPYRIGHT_ATTRIBUTION_DIR,
                    google_bsd_msg,
                )
                raise PackageLicenseError(
                    "Missing copyright attribution for "
                    f"{need_copyright_attribution}"
                )
            else:
                # We can get called for a license like as-is where it's
                # preferable to find a better one in the source, but not fatal
                # if we didn't.
                logging.info(
                    "Was not able to find a better license for %s "
                    "in %s to replace the more generic one from ebuild",
                    self.fullnamerev,
                    src_dir,
                )

        # Examples of multiple license matches:
        # dev-lang/swig-2.0.4-r1: swig-2.0.4/COPYRIGHT swig-2.0.4/LICENSE
        # dev-libs/glib-2.32.4-r1: glib-2.32.4/COPYING pkg-config-0.26/COPYING
        # dev-libs/libnl-3.2.14: libnl-doc-3.2.14/COPYING libnl-3.2.14/COPYING
        # dev-libs/libpcre-8.30-r2: pcre-8.30/LICENCE pcre-8.30/COPYING
        # dev-libs/libusb-0.1.12-r6: libusb-0.1.12/COPYING libusb-0.1.12/LICENSE
        # dev-libs/pyzy-0.1.0-r1: db/COPYING pyzy-0.1.0/COPYING
        # net-misc/strongswan-5.0.2-r4: strongswan-5.0.2/COPYING
        #                               strongswan-5.0.2/LICENSE
        # sys-process/procps-3.2.8_p11: debian/copyright procps-3.2.8/COPYING
        logging.info(
            "License(s) for %s: %s", self.fullnamerev, " ".join(license_files)
        )
        for license_file in sorted(license_files):
            # Joy and pink ponies. Some license_files are encoded as latin1
            # while others are utf-8 and of course you can't know but only
            # guess.
            license_path = os.path.join(src_dir, license_file)
            license_txt = ReadUnknownEncodedFile(license_path, "Adding License")

            self.license_text_scanned += [
                "Scanned Source License %s:\n\n%s" % (license_file, license_txt)
            ]

        # We used to clean up here, but there have been many instances where
        # looking at unpacked source to see where the licenses were, was useful
        # so let's disable this for now
        # self._RunEbuildPhases(['clean'])

    def LookForSkip(self):
        """Look for a reason to skip over this package.

        Sets self.skip to True if a reason was found.

        Returns:
            True if a reason was found.
        """
        if self.category in SKIPPED_CATEGORIES:
            logging.info(
                "%s in SKIPPED_CATEGORIES, skip package", self.fullname
            )
            self.skip = True

        # TODO(dgarrett): There are additional reasons that should be handled
        #   here.

        return self.skip

    def _FindEbuildPath(self):
        """Discover the path to a package's associated ebuild.

        This method is not valid during the emerge hook process.

        Returns:
            full path file name of the ebuild file for this package.

        Raises:
            AssertionError if it can't be discovered for some reason.
        """
        equery_cmd = cros_build_lib.GetSysrootToolPath(self.sysroot, "equery")
        args = [equery_cmd, "-q", "-C", "which", self.fullnamerev]
        try:
            path = cros_build_lib.run(
                args, print_cmd=True, encoding="utf-8", stdout=True
            ).stdout.strip()
        except cros_build_lib.RunCommandError:
            path = None

        # Path can be false because of an exception, or a command result.
        if not path:
            raise AssertionError(
                "_FindEbuildPath for %s failed.\n"
                "Is your tree clean? Try a rebuild?" % self.fullnamerev
            )

        logging.debug("%s -> %s", " ".join(args), path)

        if not os.access(path, os.F_OK):
            raise AssertionError("Can't access %s" % (path,))

        return path

    def GetLicenses(self, build_info_dir, src_dir) -> None:
        """Populate the license related fields.

        Fields populated:
            license_names, license_text_scanned, homepages, skip, tainted

        Some packages have static license mappings applied to them that get
        retrieved from the ebuild.

        For others, we figure out whether the package source should be scanned
        to add licenses found there.

        Args:
            build_info_dir: Path to the build_info for the ebuild. This can be
                from the working directory during the emerge hook, or in the
                portage pkg db.
            src_dir: Directory to the expanded source code for this package.
                If None, the source will be expanded, if needed (slow).

        Raises:
            AssertionError: on runtime errors
            PackageLicenseError: couldn't find license in ebuild and source.
        """
        # If the total size installed is zero, we installed no content to
        # license.
        if _BuildInfo(build_info_dir, "SIZE").strip() == "0":
            # Allow for license generation for the exempt empty packages.
            if self.fullname not in SIZE_EXEMPT_PACKAGES:
                logging.debug("Build directory is empty")
                self.skip = True
                return

        self.homepages = _BuildInfo(build_info_dir, "HOMEPAGE").split()
        licenses = ebuild_license.parse(_BuildInfo(build_info_dir, "LICENSE"))

        # The ebuild license field can look like:
        # LICENSE="GPL-3 LGPL-3 Apache-2.0" (this means AND, as in all 3)
        # for third_party/portage-stable/app-admin/rsyslog/rsyslog-5.8.11.ebuild
        # LICENSE="|| ( LGPL-2.1 MPL-1.1 )"
        # for third_party/portage-stable/x11-libs/cairo/cairo-1.8.8.ebuild
        #
        # In order to save time needlessly unpacking packages and looking or a
        # cleartext license (which is really a crapshoot), if we have a license
        # like BSD that requires looking for copyright attribution, but we can
        # chose another license like GPL, we do that.
        def license_picker(choices):
            for choice in choices:
                if choice not in COPYRIGHT_ATTRIBUTION_LICENSES:
                    logging.info(
                        "Picking license '%s' from %s", choice, choices
                    )
                    return choice
            return choices[0]

        ebuild_license_names = licenses.reduce(anyof_reduce=license_picker)

        # Is this tainted?
        self.tainted = TAINTED in ebuild_license_names
        if self.tainted:
            logging.warning("Package %s is tainted", self.fullnamerev)

        # If this ebuild only uses skipped licenses, skip it.
        if ebuild_license_names and all(
            l in SKIPPED_LICENSES for l in ebuild_license_names
        ):
            self.skip = True

        if self.skip:
            return

        logging.info(
            "Read licenses for %s: %s",
            self.fullnamerev,
            ",".join(ebuild_license_names),
        )

        if not self.skip and not ebuild_license_names:
            logging.error(
                "%s: no license found in ebuild. FIXME!", self.fullnamerev
            )
            # In a bind, you could comment this out. I'm making the output fail
            # to get your attention since this error really should be fixed, but
            # if you comment out the next line, the script will try to find a
            # license inside the source.
            raise PackageLicenseError()

        need_copyright_attribution = set()
        scan_source_for_licenses = False

        for license_name in ebuild_license_names:
            # Licenses like BSD or MIT can't be used as is because they do not
            # contain copyright self. They have to be replaced by copyright file
            # given in the source code.
            if license_name in COPYRIGHT_ATTRIBUTION_LICENSES:
                logging.info(
                    "%s: can't use %s, will scan source code for copyright",
                    self.fullnamerev,
                    license_name,
                )
                need_copyright_attribution.add(license_name)
                scan_source_for_licenses = True
            else:
                self.license_names.add(license_name)
                # We can't display just 2+ because it only contains text that
                # says to read v2 or v3.
                if license_name == "GPL-2+":
                    self.license_names.add("GPL-2")
                if license_name == "LGPL-2+":
                    self.license_names.add("LGPL-2")

            if license_name in LOOK_IN_SOURCE_LICENSES:
                logging.info(
                    "%s: Got %s, will try to find better license in source...",
                    self.fullnamerev,
                    license_name,
                )
                scan_source_for_licenses = True

        if self.license_names:
            logging.info(
                "%s: using stock|cust license(s) %s",
                self.fullnamerev,
                ",".join(self.license_names),
            )

        # If the license(s) could not be found, or one requires copyright
        # attribution, dig in the source code for license files:
        # For instance:
        # Read licenses from ebuild for net-dialup/ppp-2.4.5-r3: BSD,GPL-2
        # We need get the substitution file for BSD and add it to GPL.
        if scan_source_for_licenses:
            self._ExtractLicenses(src_dir, need_copyright_attribution)

        # This shouldn't run, but leaving as basic smoke check.
        if not self.license_names and not self.license_text_scanned:
            raise AssertionError(
                "Didn't find usable licenses for %s" % self.fullnamerev
            )

    def SaveLicenseDump(self, save_file) -> None:
        """Save PackageInfo contents for loading later.

        This is used to cache license results between the emerge hook phase and
        credits page generation.

        Args:
            save_file: File to save the state into.
        """
        logging.debug("Saving license to %s", save_file)
        dump = {}
        for key, value in list(self.__dict__.items()):
            if isinstance(value, set):
                value = sorted(value)
            dump[key] = value
        osutils.WriteFile(save_file, json.dumps(dump), makedirs=True)

    def AssertCorrectness(self, build_info_dir, ebuild_path) -> None:
        """AssertCorrectness runs various correctness checks on the package.

        Args:
            build_info_dir: Path to the build_info for the ebuild. This can be
                from the working directory during the emerge hook, or in the
                portage pkg db.
            ebuild_path: Path to the ebuild. Unknown and therefore None during
                the emerge hook.

        Raises:
            PackageCorrectnessError: if one of the checks fails.
        """
        self._AssertMetapackageNoContent(build_info_dir)
        if ebuild_path is not None:
            self._AssertVirtualIsMetapackage(build_info_dir, ebuild_path)

    def _AssertMetapackageNoContent(self, build_info_dir) -> None:
        """Ensures metapackages do not install files.

        Args:
            build_info_dir: Path to the build_info for the ebuild. This can be
                from the working directory during the emerge hook, or in the
                portage pkg db.

        Raises:
            PackageCorrectnessError: if metapackage installs files.
        """
        if _BuildInfo(build_info_dir, "LICENSE") == "metapackage":
            content = _BuildInfo(build_info_dir, "CONTENTS")
            if content:
                content_list = ", ".join(
                    x.split()[1] for x in content.splitlines()
                )
                raise PackageCorrectnessError(
                    "Metapackage %s installs files: %s."
                    % (self.fullnamerev, content_list)
                )

    def _AssertVirtualIsMetapackage(self, build_info_dir, ebuild_path) -> None:
        """Ensures that virtual pkgs are metapackages.

        Args:
            ebuild_path: Path to the ebuild.
            build_info_dir: Path to the build_info for the ebuild. This can be
                from the working directory during the emerge hook, or in the
                portage pkg db.

        Raises:
            PackageCorrectnessError: if virtual pkg does not use metapackage
                license.
        """
        category = ebuild_path.split("/")[-3]
        overlay = ebuild_path.split("/")[-4]
        license_name = _BuildInfo(build_info_dir, "LICENSE")
        if category == "virtual" and license_name != "metapackage":
            err_msg = (
                f"Virtual package {ebuild_path} must use LICENSE="
                f'"metapackage". Got: {self.license_names}.'
            )
            if overlay in OVERLAYS_METAPACKAGES_MUST_USE_VIRTUAL:
                raise PackageCorrectnessError(err_msg)
            else:
                logging.warning(err_msg)


def _GetLicenseDirectories(
    board: Optional[str] = None,
    sysroot: Optional[str] = None,
    dir_set: str = _BOTH_DIRS,
    buildroot: Path = constants.SOURCE_ROOT,
) -> List[str]:
    """Get the "licenses" directories for all matching overlays.

    With a |board| argument, allows searching without a compiled sysroot.

    Args:
        board: Which board to use to search a hierarchy. Does not require the
            board be setup or compiled yet.
        sysroot: A setup board sysroot to query.
        dir_set: Whether to fetch stock, custom, or both sets of directories.
            See the _(STOCK|CUSTOM|BOTH)_DIRS constants.
        buildroot: The root chromiumos path.

    Returns:
        list - all matching "licenses" directories
    """
    stock = [os.path.join(buildroot, d) for d in STOCK_LICENSE_DIRS]
    if board is not None:
        custom_paths = portage_util.FindOverlays(
            constants.BOTH_OVERLAYS, board, buildroot
        )
    elif sysroot is not None and sysroot != "/":
        portdir_overlay = (
            sysroot_lib.Sysroot(sysroot).GetStandardField(
                sysroot_lib.STANDARD_FIELD_PORTDIR_OVERLAY
            )
            or ""
        )
        custom_paths = portdir_overlay.split() if portdir_overlay else []
    else:
        custom_paths = [
            os.path.join(constants.SOURCE_ROOT, x) for x in SDK_OVERLAY_DIRS
        ]
    custom = [os.path.join(d, "licenses") for d in custom_paths]

    if dir_set == _STOCK_DIRS:
        return stock
    elif dir_set == _CUSTOM_DIRS:
        return custom
    else:
        return stock + custom


def _CheckForKnownBadLicenses(cpf, licenses) -> None:
    """Make sure all the |licenses| are ones we allow.

    We have a bunch of licenses we don't want people to use, but some packages
    were using them by the time we noticed.  Still allow those existing ones,
    but prevent new users from showing up.
    """
    bad_licenses = set()
    for pattern in BAD_LICENSE_PATTERNS:
        bad_licenses |= {x for x in licenses if fnmatch.fnmatch(x, pattern)}

    # We allow ghostscript for public builds to use AGPL but nothing else.
    if cpf.startswith("app-text/ghostscript-gpl"):
        bad_licenses -= {"AGPL-3"}

    if bad_licenses:
        raise PackageLicenseError(f"Licenses {bad_licenses} are not allowed")

    # TODO(crbug.com/401332): Remove this entirely.
    # We allow a few packages for now so new packages will stop showing up.
    if "Proprietary-Binary" in licenses:
        # Note: DO NOT ADD ANY MORE PACKAGES HERE.
        LEGACY_PKGS = (
            "chromeos-base/infineon-firmware",
            "sys-boot/coreboot-private-files-",
            "sys-boot/nhlt-blobs",
            "sys-boot/mma-blobs",
        )
        if not any(cpf.startswith(x) for x in LEGACY_PKGS):
            raise PackageLicenseError(
                f"{cpf}: Proprietary-Binary is not a valid license."
            )

    # TODO(b/187789754): Remove this entirely.
    # We allow a few packages for now so new packages will stop showing up.
    if "Google-TOS" in licenses:
        # Note: DO NOT ADD ANY MORE PACKAGES HERE.
        LEGACY_PKGS = {
            "chromeos-base/chromeos-board-default-apps-atlas",
            "chromeos-base/chromeos-board-default-apps-cave",
            "chromeos-base/chromeos-board-default-apps-chell",
            "chromeos-base/chromeos-board-default-apps-nocturne",
            "chromeos-base/chromeos-board-default-apps-setzer",
            "chromeos-base/chromeos-board-default-apps-snappy",
            "chromeos-base/chromeos-board-default-apps-soraka",
            "chromeos-base/chromeos-board-default-apps-terra",
            "chromeos-base/chromeos-bsp-trogdor-private",
            "chromeos-base/chromeos-chrome",
            "chromeos-base/chromeos-default-apps",
            "chromeos-base/chromeos-firmware-anx7688",
            "chromeos-base/fibocom-firmware",
            "chromeos-base/google-sans-fonts",
            "chromeos-base/houdini",
            "chromeos-base/houdini-pi",
            "chromeos-base/houdini-qt",
            "chromeos-base/intel-hdcp",
            "chromeos-base/monotype-fonts",
            "chromeos-base/qc7180-modem-firmware",
            "chromeos-base/sc7280-modem-firmware",
            "chromeos-base/modem-logger-sc",
            "chromeos-base/modem-fw-dlc",
            "dev-embedded/meta-embedded-toolkit",
            "media-libs/a630-fw",
            "media-libs/apl-hotword-support",
            "media-libs/arc-img-ddk",
            "media-libs/arc-mali-drivers",
            "media-libs/arc-mali-drivers-bifrost",
            "media-libs/cros-camera-hal-qti",
            "media-libs/cros-camera-hal-qti-bin",
            "media-libs/glk-hotword-support",
            "media-libs/go2001-fw",
            "media-libs/img-ddk",
            "media-libs/img-ddk-bin",
            "media-libs/kbl-hotword-support",
            "media-libs/kbl-rt5514-hotword-support",
            "media-libs/mali-drivers",
            "media-libs/mali-drivers-bifrost",
            "media-libs/mali-drivers-bifrost-bin",
            "media-libs/mali-drivers-bin",
            "media-libs/qti-7c-camera-bins",
            "media-libs/rk3399-hotword-support",
            "media-libs/skl-hotword-support",
            "net-print/brother_mlaser",
            "sys-apps/loonix-hydrogen",
            "sys-boot/chromeos-firmware-ps8751",
            "sys-boot/chromeos-vendor-strings-wilco",
            "sys-boot/coreboot-private-files-chipset-picasso",
            "sys-boot/coreboot-private-files-chipset-stnyridge",
            "sys-boot/coreboot-private-files-drallion",
            "sys-boot/coreboot-private-files-grunt",
            "sys-boot/coreboot-private-files-hatch",
            "sys-boot/amd-picasso-fsp",
            "sys-boot/intel-cflfsp",
            "sys-boot/intel-glkfsp",
            "sys-boot/intel-iclfsp",
            "sys-boot/mma-blobs",
            "sys-boot/nhlt-blobs",
            "sys-boot/rk3399-hdcp-fw",
            "sys-boot/qclib",
            "sys-boot/qtiseclib",
            "sys-firmware/analogix-anx3429-firmware",
            "sys-firmware/displaylink-firmware",
            "sys-firmware/falcon-firmware",
            "sys-firmware/huddly-firmware",
            "sys-firmware/iq-firmware",
            "sys-firmware/sis-firmware",
        }
        if not any(cpf.startswith(x) for x in LEGACY_PKGS):
            raise PackageLicenseError(
                f"{cpf}: Google-TOS is not a valid license."
            )


class Licensing:
    """Do the actual work of extracting licensing info and outputting html."""

    def __init__(
        self,
        sysroot,
        package_fullnames,
        gen_licenses,
        placeholder: bool = False,
    ) -> None:
        self.sysroot = sysroot
        # List of stock and custom licenses referenced in ebuilds. Used to
        # print a report. Dict value says which packages use that license.
        self.licenses = {}

        # Licenses are supposed to be generated at package build time and be
        # ready for us, but in case they're not, they can be generated.
        self.gen_licenses = gen_licenses

        # Generate placeholder values instead of inspecting real data.
        self.placeholder = placeholder

        self.entry_template = None

        # We need to have a dict for the list of packages objects, index by
        # package fullnamerev, so that when we scan our licenses at the end, and
        # find out some shared licenses are only used by one package, we can
        # access that package object by name, and add the license directly in
        # that object.
        self.packages = {}
        self._package_fullnames = package_fullnames

        # Set by ProcessPackageLicenses().
        self.tainted_pkgs = []

    @property
    def sorted_licenses(self):
        return sorted(self.licenses, key=lambda x: x.lower())

    def _LoadLicenseDump(self, pkg) -> None:
        save_file = pkg.license_dump_path
        logging.debug("Getting license from %s for %s", save_file, pkg.name)
        with open(save_file, "rb") as fp:
            dump = json.load(fp)
        for key, value in dump.items():
            if isinstance(pkg.__dict__[key], set):
                value = set(value)
            pkg.__dict__[key] = value

    def LicensedPackages(self, license_name):
        """Return list of packages using a given license."""
        return self.licenses[license_name]

    def LoadPackageInfo(self) -> None:
        """Populate basic package info for all packages from their ebuild."""
        for package_name in self._package_fullnames:
            pkg = PackageInfo(self.sysroot, package_name)
            self.packages[package_name] = pkg

    def ProcessPackageLicenses(self) -> None:
        """Iterate through all packages provided and gather their licenses.

        GetLicenses will scrape licenses from the code and/or gather stock
        license names. We gather the list of stock and custom ones for later
        processing.

        Do not call this after adding virtual packages with AddExtraPkg.
        """
        # TODO(b/236161656): Fix.
        # pylint: disable-next=consider-using-dict-items
        for package_name in self.packages:
            pkg = self.packages[package_name]

            if pkg.skip:
                logging.debug("Package %s is in skip list", package_name)
                continue

            if self.placeholder:
                pkg.license_names = ["Placeholder-License"]
                pkg.license_text_scanned = ["Custom placeholder license text"]
                pkg.homepages = ["https://dev.chromium.org/"]
                continue

            # Do inplace/ondemand migration.
            if not os.path.exists(pkg.license_dump_path):
                yaml_file = pkg.license_dump_path[0:-4] + "yaml"
                if os.path.exists(yaml_file):
                    _convert_yaml_to_json(yaml_file, pkg.license_dump_path)

            # Other skipped packages get dumped with incomplete info and the
            # skip flag
            if not os.path.exists(pkg.license_dump_path):
                if not self.gen_licenses:
                    logging.error(
                        "Run licenses.py with --generate-licenses to try to "
                        "generate the missing licenses."
                    )
                    raise PackageLicenseError(
                        f"{pkg.fullnamerev}: license is missing"
                    )

                logging.warning(
                    ">>> License for %s is missing, creating now <<<",
                    package_name,
                )
                build_info_path = os.path.join(
                    self.sysroot, PER_PKG_LICENSE_DIR, pkg.fullnamerev
                )
                pkg.GetLicenses(build_info_path, None)
                pkg.AssertCorrectness(build_info_path, self.ebuild_path)

                # We dump packages where licensing failed too.
                pkg.SaveLicenseDump(pkg.license_dump_path)

            # Load the pre-cached version, if the in-memory version is
            # incomplete.
            if not pkg.license_names:
                logging.debug("loading dump for %s", pkg.fullnamerev)
                self._LoadLicenseDump(pkg)

            # Store all tainted packages to print at the top of generated
            # license. If any package is tainted, the whole thing is tainted.
            if pkg.tainted:
                self.tainted_pkgs.append(package_name)

            _CheckForKnownBadLicenses(pkg.fullnamerev, pkg.license_names)

    def AddExtraPkg(
        self, fullnamerev, homepages, license_names, license_texts
    ) -> None:
        """Allow adding pre-created virtual packages.

        GetLicenses will not work on them, so add them after having run
        ProcessPackages.

        Args:
            fullnamerev: package name of the form x11-base/X.Org-1.9.3-r23
            homepages: list of url strings.
            license_names: list of license name strings.
            license_texts: custom license text to use, mostly for attribution.
        """
        pkg = PackageInfo(self.sysroot, fullnamerev)
        pkg.homepages = homepages
        pkg.license_names = license_names
        pkg.license_text_scanned = license_texts
        self.packages[fullnamerev] = pkg

        _CheckForKnownBadLicenses(fullnamerev, pkg.license_names)

    # Called directly by src/repohooks/pre-upload.py
    @staticmethod
    def FindLicenseType(
        license_name,
        board=None,
        sysroot=None,
        overlay_path=None,
        buildroot=constants.SOURCE_ROOT,
        placeholder: bool = False,
    ):
        """Says if a license is stock Gentoo, custom, tainted, or doesn't exist.

        Will check the old, static locations by default, but supplying either
        the overlay directory or sysroot allows searching in the overlay
        hierarchy. Ignores the overlay_path if sysroot is provided.

        Args:
            license_name: The license name
            board: Which board to use to search a hierarchy. Does not require
                the board be setup or compiled yet.
            sysroot: A setup board sysroot to query.
            overlay_path: Which overlay directory to use as the search base
            buildroot: source root
            placeholder: Whether to generate a stub placeholder page.

        Returns:
            str - license type

        Raises:
            AssertionError when the license couldn't be found
        """
        if license_name == TAINTED:
            return TAINTED

        if placeholder:
            return "Placeholder Stock"

        # Check the stock licenses first since those may appear in the generated
        # list of overlay directories for a board
        stock = _GetLicenseDirectories(dir_set=_STOCK_DIRS, buildroot=buildroot)
        for directory in stock:
            path = os.path.join(directory, license_name)
            if os.path.exists(path):
                return "Gentoo Package Stock"

        # Not stock, find and check relevant custom directories
        if board is None and overlay_path is not None:
            board = portage_util.GetOverlayName(overlay_path)

        # Check the custom licenses
        custom = _GetLicenseDirectories(
            board=board,
            sysroot=sysroot,
            dir_set=_CUSTOM_DIRS,
            buildroot=buildroot,
        )
        for directory in custom:
            path = os.path.join(directory, license_name)
            if os.path.exists(path):
                return "Custom"

        if license_name in SKIPPED_LICENSES:
            return "Custom"

        raise AssertionError(
            """
license %s could not be found in %s
If the license in the ebuild is correct,
a) a stock license should be added to portage-stable/licenses :
running `cros_portage_upgrade` inside of the chroot should clone this repo
to /tmp/portage/:
https://chromium.googlesource.com/chromiumos/overlays/portage/+/gentoo
find the new licenses under licenses, and add them to portage-stable/licenses

b) if it's a non gentoo package with a custom license, you can copy that license
to third_party/chromiumos-overlay/licenses/

Try re-running the script with -p cat/package-ver --generate
after fixing the license."""
            % (license_name, "\n".join(set(stock + custom)))
        )

    @staticmethod
    def ReadSharedLicense(
        license_name,
        board=None,
        sysroot=None,
        buildroot=constants.SOURCE_ROOT,
        placeholder: bool = False,
    ):
        """Read and return stock or cust license file specified in an ebuild."""
        if placeholder:
            return "Placeholder license text"

        directories = _GetLicenseDirectories(
            board=board,
            sysroot=sysroot,
            dir_set=_BOTH_DIRS,
            buildroot=buildroot,
        )
        license_path = None
        for directory in directories:
            path = os.path.join(directory, license_name)
            if os.path.exists(path):
                license_path = path
                break

        if license_path:
            return ReadUnknownEncodedFile(license_path, "read license")
        else:
            raise AssertionError(
                "license %s could not be found in %s"
                % (license_name, "\n".join(directories))
            )

    @staticmethod
    def EvaluateTemplate(template, env):
        """Expand |template| with vars like {{foo}} using |env| expansions."""
        # TODO switch to stock python templates.
        for key, val in env.items():
            template = template.replace("{{%s}}" % key, val)
        return template

    def _GeneratePackageLicenseHTML(self, pkg, license_text):
        """Concatenate all licenses related to a pkg in HTML format.

        This means a combination of ebuild shared licenses and licenses read
        from the pkg source tree, if any.

        Args:
            pkg: PackageInfo object
            license_text: the license in plain text.

        Returns:
            The license for a file->package in HTML format.

        Raises:
            AssertionError: on runtime errors
        """
        license_pointers = []
        # sln: shared license name.
        for sln in pkg.license_names:
            # Says whether it's a stock gentoo or custom license.
            try:
                license_type = self.FindLicenseType(
                    sln, sysroot=self.sysroot, placeholder=self.placeholder
                )
            except Exception as e:
                logging.error(
                    "Failed to find the type of %s license, used by %s "
                    "package. If this license is not used anymore, it may be "
                    "still cached as a binpkg—run emerge on the package to "
                    "rebuild. See more info at "
                    "https://dev.chromium.org/chromium-os/licensing",
                    sln,
                    pkg.fullnamerev,
                )
                cros_build_lib.Die(e)
            license_pointers.append(
                "<li><a href='#%s'>%s License %s</a></li>"
                % (sln, license_type, sln)
            )

        # This should get caught earlier, but one extra check.
        if not license_text + license_pointers:
            raise AssertionError(
                "Ended up with no license_text for %s" % pkg.fullnamerev
            )

        env = {
            "comments": TAINTED_COMMENT_TAG if pkg.tainted else "",
            "name": pkg.name,
            "namerev": "%s-%s" % (pkg.name, pkg.version),
            "url": html.escape(pkg.homepages[0]) if pkg.homepages else "",
            "licenses_txt": html.escape("\n".join(license_text)) or "",
            "licenses_ptr": "\n".join(license_pointers) or "",
        }
        return self.EvaluateTemplate(self.entry_template, env)

    def _GeneratePackageLicenseText(self, pkg):
        """Concatenate all licenses related to a pkg.

        This means a combination of ebuild shared licenses and licenses read
        from the pkg source tree, if any.

        Args:
            pkg: PackageInfo object
        """
        license_text = []
        for license_text_scanned in pkg.license_text_scanned:
            license_text.append(license_text_scanned)
            license_text.append("%s\n" % ("-=" * 40))

        return license_text

    def GenerateLicenseText(self):
        """Generate the license text for all packages."""
        license_txts = {}
        # Keep track of which licenses are used by which packages.
        for pkg in self.packages.values():
            if pkg.tainted:
                license_txts[pkg] = TAINTED
                continue
            if pkg.skip:
                continue
            for sln in pkg.license_names:
                self.licenses.setdefault(sln, []).append(pkg.fullnamerev)

        # Find licenses only used once, and roll them in the package that uses
        # them. We use list() because licenses is modified in the loop, so we
        # can't use an iterator.
        for sln in list(self.licenses):
            if len(self.licenses[sln]) == 1:
                pkg_fullnamerev = self.licenses[sln][0]
                logging.info(
                    "Collapsing shared license %s into single use license "
                    "(only used by %s)",
                    sln,
                    pkg_fullnamerev,
                )
                license_type = self.FindLicenseType(
                    sln, sysroot=self.sysroot, placeholder=self.placeholder
                )
                license_txt = self.ReadSharedLicense(
                    sln, sysroot=self.sysroot, placeholder=self.placeholder
                )
                single_license = "%s License %s:\n\n%s" % (
                    license_type,
                    sln,
                    license_txt,
                )
                pkg = self.packages[pkg_fullnamerev]
                pkg.license_text_scanned.append(single_license)
                pkg.license_names.remove(sln)
                del self.licenses[sln]

        for pkg in self.packages.values():
            if pkg.skip:
                logging.debug("Skipping empty package %s", pkg.fullnamerev)
                continue
            license_txts[pkg] = self._GeneratePackageLicenseText(pkg)

        return license_txts

    def GenerateHTMLLicenseOutput(
        self,
        output_file,
        output_template=TMPL,
        entry_template=ENTRY_TMPL,
        license_template=SHARED_LICENSE_TMPL,
        os_version: Optional[str] = None,
        milestone_version: Optional[str] = None,
        compress_output=False,
    ) -> None:
        """Generate the combined html license file.

        Args:
            output_file: resulting HTML license output.
            output_template: template for the entire HTML file.
            entry_template: template for per package entries.
            license_template: template for shared license entries.
            os_version: OS version.
            milestone_version: Milestone version.
            compress_output: whether to compress based on suffix of output_file.
        """
        self.entry_template = ReadUnknownEncodedFile(entry_template)
        license_txts = self.GenerateLicenseText()
        sorted_license_txt = []
        for pkg in sorted(
            license_txts.keys(),
            key=lambda x: (x.name.lower(), x.version, x.revision),
        ):
            sorted_license_txt += [
                self._GeneratePackageLicenseHTML(pkg, license_txts[pkg])
            ]

        # Now generate the bottom of the page that will contain all the shared
        # licenses and a list of who is pointing to them.
        license_template = ReadUnknownEncodedFile(license_template)

        licenses_txt = []
        for license_name in self.sorted_licenses:
            env = {
                "license_name": license_name,
                "license": html.escape(
                    self.ReadSharedLicense(
                        license_name,
                        sysroot=self.sysroot,
                        placeholder=self.placeholder,
                    )
                ),
                "license_type": self.FindLicenseType(
                    license_name,
                    sysroot=self.sysroot,
                    placeholder=self.placeholder,
                ),
                "license_packages": " ".join(
                    self.LicensedPackages(license_name)
                ),
            }
            licenses_txt += [self.EvaluateTemplate(license_template, env)]

        if self.placeholder:
            if not os_version:
                os_version = "1000.10.0"
            if not milestone_version:
                milestone_version = "100"
        reciprocal_txt = ""
        if os_version and milestone_version:
            env = {
                "chromeos-manifest-link": gs_urls_util.GsUrlToHttp(
                    "gs://chromeos-manifest-versions/buildspecs/"
                    f"{milestone_version}/{os_version}.xml"
                ),
                "chromiumos-manifest-link": gs_urls_util.GsUrlToHttp(
                    "gs://chromiumos-manifest-versions/buildspecs/"
                    f"{milestone_version}/{os_version}.xml"
                ),
                "os-version": os_version,
                "milestone-version": milestone_version,
            }
            reciprocal_txt = self.EvaluateTemplate(
                osutils.ReadFile(
                    os.path.join(SCRIPT_DIR, "about_credits_reciprocal.tmpl")
                ),
                env,
            )

        file_template = ReadUnknownEncodedFile(output_template)
        tainted_warning = ""
        if self.tainted_pkgs:
            tained_pkg_lis = "\n".join(
                f"  <li>{x}</li>" for x in self.tainted_pkgs
            )
            tainted_warning = (
                TAINTED_COMMENT_TAG
                + "\n"
                + "<h1>Image is TAINTED due to the following "
                + 'packages:</h1>\n<ul style="font-size:large">\n'
                + tained_pkg_lis
                + "\n</ul>\n"
            )
            for tainted_pkg in self.tainted_pkgs:
                logging.warning("Package %s is tainted", tainted_pkg)
            logging.warning(
                "Image is tainted. See licensing docs to fix this: "
                "https://dev.chromium.org/chromium-os/licensing"
            )
        env = {
            "tainted_warning_if_any": tainted_warning,
            "entries": "\n".join(sorted_license_txt),
            "licenses": "\n".join(licenses_txt),
            "placeholder": _PLACEHOLDER_BANNER if self.placeholder else "",
            "reciprocal-license-statement": reciprocal_txt,
        }
        contents = self.EvaluateTemplate(file_template, env).encode("utf-8")
        if not compress_output:
            # Just write it.
            osutils.WriteFile(output_file, contents, mode="wb")
        else:
            # Write to a temp file, then compress it to the final destination,
            # using the file extension specified to determine compression type.
            with cros_build_lib.UnbufferedNamedTemporaryFile() as f:
                osutils.WriteFile(f.name, contents, mode="wb")
                cros_build_lib.CompressFile(f.name, output_file)


def ListInstalledPackages(sysroot, all_packages=False):
    """Return a list of all packages installed for a particular board."""

    # If all_packages is set to True, all packages visible in the build
    # chroot are used to generate the licensing file. This is not what you want
    # for a release license file, but it's a way to run licensing checks against
    # all packages.
    # If it's set to False, it will only generate a licensing file that contains
    # packages used for a release build (as determined by the dependencies for
    # virtual/target-os).

    if all_packages:
        # The following returns all packages that were part of the build tree
        # (many get built or used during the build, but do not get shipped).
        # Note that it also contains packages that are in the build as
        # defined by cros build-packages but not part of the image we ship.
        equery_cmd = cros_build_lib.GetSysrootToolPath(sysroot, "equery")
        args = [equery_cmd, "list", "*"]
        packages = cros_build_lib.run(
            args, encoding="utf-8", stdout=True
        ).stdout.splitlines()
    else:
        # The following returns all packages that were part of the build tree
        # (many get built or used during the build, but do not get shipped).
        # Note that it also contains packages that are in the build as
        # defined by cros build-packages but not part of the image we ship.
        emerge_cmd = cros_build_lib.GetSysrootToolPath(sysroot, "emerge")
        args = [
            emerge_cmd,
            "--with-bdeps=y",
            "--usepkgonly",
            "--emptytree",
            "--pretend",
            "--color=n",
            "virtual/target-os",
        ]
        emerge = cros_build_lib.run(
            args, encoding="utf-8", stdout=True
        ).stdout.splitlines()
        # Another option which we've decided not to use, is bdeps=n.  This
        # outputs just the packages we ship, but not packages that were used to
        # build them, including a package like flex which generates a .a that is
        # included and shipped in ChromeOS.
        # We've decided to credit build packages, even if we're not legally
        # required to (it's always nice to do), and that way we get corner case
        # packages like flex. This is why we use bdep=y and not bdep=n.

        packages = []
        bad_packages = []
        # [binary   R    ] x11-libs/libva-1.1.1 to /build/x86-alex/
        pkg_rgx = re.compile(r"\[[^]]+R[^]]+\] (.+) to /build/.*")
        # pylint: disable=line-too-long
        # If we match something else without the 'R' like
        # [binary     U  ] chromeos-base/some-package-13.0.0.133-r1 [12.0.0.77-r1]
        # this is bad, and we should die on this.
        # pylint: enable=line-too-long
        pkg_rgx2 = re.compile(r"(\[[^]]+\] .+) to /build/.*")
        for line in emerge:
            match = pkg_rgx.search(line)
            match2 = pkg_rgx2.search(line)
            if match:
                packages.append(match.group(1))
            elif match2:
                bad_packages.append(match2.group(1))

        if bad_packages:
            raise AssertionError(
                "Package incorrectly installed, try reinstalling",
                "\n%s" % "\n".join(bad_packages),
            )

    return packages


def FilterLicenseFileCandidates(stdout: str) -> List[str]:
    """Returns the subset of files in `stdout` that look like licenses."""
    license_files: List[str] = []
    basename_include_pattern = re.compile(
        "|".join(f"({x})" for x in LICENSE_BASENAMES_REGEX), re.IGNORECASE
    )
    path_exclude_pattern = re.compile(
        "|".join(f"({x})" for x in LICENSE_PATHS_EXCLUDE_REGEX), re.IGNORECASE
    )
    for path in stdout.splitlines():
        # When we scan a source tree managed by git, this can contain license
        # files that are not part of the source. Exclude those.
        # (e.g. .git/refs/heads/licensing)
        if ".git/" in path:
            continue
        basename = os.path.basename(path)
        if basename_include_pattern.search(basename):
            if path_exclude_pattern.search(path):
                logging.info("Ignoring %s (matches exclude regex).", path)
            else:
                license_files.append(path)
    return license_files


def ReadUnknownEncodedFile(file_path, logging_text=None):
    """Read a file of unknown encoding (UTF-8 or latin) by trying in sequence.

    Args:
        file_path: what to read.
        logging_text: what to display for logging depending on file read.

    Returns:
        File content, possibly converted from latin1 to UTF-8.
    """
    try:
        with codecs.open(file_path, encoding="utf-8") as c:
            file_txt = c.read()
            if logging_text:
                logging.info("%s %s (UTF-8)", logging_text, file_path)
    except UnicodeDecodeError:
        with codecs.open(file_path, encoding="latin1") as c:
            file_txt = c.read()
            if logging_text:
                logging.info("%s %s (latin1)", logging_text, file_path)

    # Remove characters that are not XML 1.0 legal.
    # XML 1.0 acceptable character range:
    # Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | \
    #          [#x10000-#x10FFFF]

    # Strip out common/OK values silently.
    silent_chars_re = re.compile("[\x0c]")
    file_txt = silent_chars_re.sub("", file_txt)

    illegal_chars_re = re.compile(
        "[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]"
    )

    if illegal_chars_re.findall(file_txt):
        logging.warning("Found illegal XML characters, stripping them out.")
        file_txt = illegal_chars_re.sub("", file_txt)

    return file_txt


def _BuildInfo(build_info_path, filename):
    """Fetch contents of a file from portage build_info directory.

    Portage maintains a build_info directory that exists both during the process
    of emerging an ebuild, and (in a different location) after the ebuild has
    been emerged.

    Various useful data files exist there like:
        'CATEGORY', 'PF', 'SIZE', 'HOMEPAGE', 'LICENSE'

    Args:
        build_info_path: Path to the build_info directory to read from.
        filename: Name of the file to read.

    Returns:
        Contents of the file as a string, or "".
    """
    filename = os.path.join(build_info_path, filename)

    # Buildinfo properties we read are in US-ASCII, not Unicode.
    try:
        bi = osutils.ReadFile(filename).rstrip()
    # Some properties like HOMEPAGE may be absent.
    except IOError:
        bi = ""
    return bi


def HookPackageProcess(
    pkg_build_path: str, sysroot: Optional[str] = "/"
) -> None:
    """Different entry point to populate a packageinfo.

    This is called instead of LoadPackageInfo when called by a package build.

    Args:
        pkg_build_path: unpacked being built by emerge.
        sysroot: The sysroot we're building for.
    """
    build_info_dir = os.path.join(pkg_build_path, "build-info")
    if not os.path.isdir(build_info_dir):
        raise ValueError(
            '%s is not a valid build path (missing "build-info/")'
            % (pkg_build_path,)
        )

    fullnamerev = "%s/%s" % (
        _BuildInfo(build_info_dir, "CATEGORY"),
        _BuildInfo(build_info_dir, "PF"),
    )
    logging.debug(
        "Computed package name %s from %s", fullnamerev, pkg_build_path
    )

    pkg = PackageInfo(None, fullnamerev)

    src_dir = os.path.join(pkg_build_path, "work")
    pkg.GetLicenses(build_info_dir, src_dir)

    pkg.AssertCorrectness(build_info_dir, None)
    # Make sure the licenses are valid at build time even if we don't load them.
    _CheckForKnownBadLicenses(fullnamerev, pkg.license_names)
    for license_name in pkg.license_names:
        Licensing.FindLicenseType(license_name, sysroot=sysroot)

    pkg.SaveLicenseDump(os.path.join(build_info_dir, "license.json"))
