# -*- coding: utf-8 -*-
# Copyright 2012 The Chromium OS Authors. All rights reserved.
# 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
"""

from __future__ import print_function

import codecs
import html  # pylint: disable=import-error
import os
import re
from typing import List, Optional

from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib.parser import package_info

# We are imported by src/repohooks/pre-upload.py in a non chroot environment
# where yaml may not be there, so we don't error on that since it's not needed
# in that case.
try:
  # pylint: disable=wrong-import-order
  import yaml
except ImportError:
  yaml = None

# 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_NAMES_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)
]

# These are _temporary_ license mappings for packages that do not have a valid
# shared/custom license, or LICENSE file we can use.
# Once this script runs earlier (during the package build process), it will
# block new source without a LICENSE file if the ebuild contains a license
# that requires copyright assignment (BSD and friends).
# At that point, new packages will get fixed to include LICENSE instead of
# adding workaround mappings like those below.
# The way you now fix copyright attribution cases create a custom file with the
# right license directly in COPYRIGHT_ATTRIBUTION_DIR.
PACKAGE_LICENSES = {
    # TODO: replace the naive license parsing code in this script with a hook
    # into portage's license parsing. See https://crbug.com/348779

    # Chrome (the browser) is complicated, it has a morphing license that is
    # either BSD-Google, or BSD-Google,Google-TOS depending on how it was
    # built. We bypass this problem for now by hardcoding the Google-TOS bit as
    # per ChromeOS with non free bits
    'chromeos-base/chromeos-chrome': ['BSD-Google', 'Google-TOS'],

    # Currently the code cannot parse embedded || (...) syntax.
    'app-admin/eselect': ['GPL-2+'],
    'dev-python/pycairo': ['LGPL-3', 'LGPL-2.1'],
    'dev-lang/yasm': ['BSD-2', 'GPL-2', 'LGPL-2'],
    'dev-ruby/rubygems': ['GPL-2', 'MIT'],

    # Currently the code cannot parse the license for mit-krb5
    # "openafs-krb5-a BSD MIT OPENLDAP BSD-2 HPND BSD-4 ISC RSA CC-BY-SA-3.0 ||
    #      ( BSD-2 GPL-2+ )"
    'app-crypt/mit-krb5': [
        'openafs-krb5-a',
        'BSD',
        'MIT',
        'OPENLDAP',
        'BSD-2',
        'HPND',
        'BSD-4',
        'ISC',
        'RSA',
        'CC-BY-SA-3.0',
        'GPL-2+',
    ],
}

# Any license listed list 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-3',  # and BSD-3? https://opensource.org/licenses/BSD-3-Clause
    'BSD-4',  # and 4?
    'BSD-with-attribution',
    '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 = [
    'as-is',  # The stock license is very vague, source always has more details.
    '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.
]

# This used to provide overrides. I can't find a valid reason to add any more
# here, though.
PACKAGE_HOMEPAGES = {
    # Example:
    # 'x11-proto/glproto': ['http://www.x.org/'],
}

# These are tokens found in LICENSE= in an ebuild that aren't licenses we
# can actually read from disk.
# You should not use this to blacklist real licenses.
LICENCES_IGNORE = [
    ')',              # Ignore OR tokens from LICENSE="|| ( LGPL-2.1 MPL-1.1 )"
    '(',
    '||',
]

# 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/konica-minolta-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'


# 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, whitelist=['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 if something fails while getting license information for a package.

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


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

  def __init__(self, sysroot, fullnamerev):
    """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'
    """

    self.sysroot = sysroot

    #
    # Populate these fields from fullnamerev:
    #   category, name, version, revision
    #
    try:
      cpv = package_info.SplitCPV(fullnamerev)
    except ValueError:
      # A bad package can either raise a TypeError exception or return None.
      raise ValueError(
          "portage couldn't find %s, missing version number?" % fullnamerev)

    #
    # These define the package uniquely.
    #

    self.category, self.name, self.version, self.revision = (
        cpv.category, cpv.package, cpv.version_no_rev, cpv.rev)

    if self.revision is not None:
      self.revision = str(self.revision).lstrip('r')

    #
    # 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

  @property
  def fullnamerev(self):
    """e.g. libnl/libnl-3.2.24-r12"""
    s = '%s-%s' % (self.fullname, self.version)
    if self.revision:
      s += '-r%s' % self.revision
    return s

  @property
  def fullname(self):
    """e.g. libnl/libnl-3.2.24"""
    return '%s/%s' % (self.category, self.name)

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

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

  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):
    """Look in COPYRIGHT_ATTRIBUTION_DIR for license with 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
        # /../merlin/trunk/src/third_party/chromiumos-overlay/../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):
    """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_NAMES_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:
      ebuild_path = self._FindEbuildPath()
      self._RunEbuildPhases(ebuild_path, ['clean', 'fetch'])
      raw_output = self._RunEbuildPhases(ebuild_path, ['unpack'])
      output = raw_output.output.splitlines()
      # 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.
      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))

    # 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
    args = ['find', src_dir, '-type', 'f']
    result = cros_build_lib.run(args, stdout=True, encoding='utf-8')
    # Truncate results to look like this: swig-2.0.4/COPYRIGHT
    files = [x[len(src_dir):].lstrip('/') for x in result.stdout.splitlines()]
    license_files = []
    for name in files:
      # 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 name:
        continue
      basename = os.path.basename(name)
      # Looking for license.* brings up things like license.gpl, and we
      # never want a GPL license when looking for copyright attribution,
      # so we skip them here. We also skip regexes that can return
      # license.py (seen in some code).
      if re.search(r'.*GPL.*', basename) or re.search(r'\.py$', basename):
        continue
      for regex in LICENSE_NAMES_REGEX:
        if re.search(regex, basename, re.IGNORECASE):
          license_files.append(name)
          break

    if not license_files:
      if need_copyright_attribution:
        logging.error("""
%s: unable to find usable license.
Typically this will happen because the ebuild says it's MIT or BSD, but there
was no license file that this script could find to include along with a
copyright attribution (required for BSD/MIT).

If this is Google source, please change
LICENSE="BSD"
to
LICENSE="BSD-Google"

If not, go investigate the unpacked source in %s,
and find which license to assign.  Once you found it, you should copy that
license to a file under %s
(or you can modify LICENSE_NAMES_REGEX to pickup a license file that isn't
being scraped currently).""",
                      self.fullnamerev, src_dir, COPYRIGHT_ATTRIBUTION_DIR)
        raise PackageLicenseError()
      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).output.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):
    """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 whitelisted 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()
    ebuild_license_names = _BuildInfo(build_info_dir, 'LICENSE').split()

    # 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

    if self.fullname in PACKAGE_HOMEPAGES:
      self.homepages = PACKAGE_HOMEPAGES[self.fullname]

    # Packages with missing licenses or licenses that need mapping (like
    # BSD/MIT) are hardcoded here:
    if self.fullname in PACKAGE_LICENSES:
      ebuild_license_names = PACKAGE_LICENSES[self.fullname]
      logging.info('Static license mapping for %s: %s', self.fullnamerev,
                   ','.join(ebuild_license_names))
    else:
      logging.info('Read licenses for %s: %s', self.fullnamerev,
                   ','.join(ebuild_license_names))

    # Lots of packages in chromeos-base have their license set to BSD instead
    # of BSD-Google:
    new_license_names = []
    for license_name in ebuild_license_names:
      # TODO: temp workaround for http;//crbug.com/348750 , remove when the bug
      # is fixed.
      if (license_name == 'BSD' and
          self.fullnamerev.startswith('chromeos-base/') and
          'BSD-Google' not in ebuild_license_names):
        license_name = 'BSD-Google'
        logging.warning(
            "Fixed BSD->BSD-Google for %s because it's in chromeos-base. "
            'Please fix the LICENSE field in the ebuild', self.fullnamerev)
      new_license_names.append(license_name)
    ebuild_license_names = new_license_names

    # 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

    # The parser isn't very smart and only has basic support for the
    # || ( X Y ) OR logic to do the following:
    # 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.

    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()

    # This is not invalid, but the parser can't deal with it, so if it ever
    # happens, error out to tell the programmer to do something.
    # dev-python/pycairo-1.10.0-r4: LGPL-3 || ( LGPL-2.1 MPL-1.1 )
    if '||' in ebuild_license_names[1:]:
      logging.error("%s: Can't parse || in the middle of a license: %s",
                    self.fullnamerev, ' '.join(ebuild_license_names))
      raise PackageLicenseError()

    or_licenses_and_one_is_no_attribution = False
    # We do a quick early pass first so that the longer pass below can
    # run accordingly.
    for license_name in [x for x in ebuild_license_names
                         if x not in LICENCES_IGNORE]:
      # Here we have an OR case, and one license that we can use stock, so
      # we remember that in order to be able to skip license attributions if
      # any were in the OR.
      if (ebuild_license_names[0] == '||' and
          license_name not in COPYRIGHT_ATTRIBUTION_LICENSES):
        or_licenses_and_one_is_no_attribution = True

    need_copyright_attribution = False
    scan_source_for_licenses = False

    for license_name in [x for x in ebuild_license_names
                         if x not in LICENCES_IGNORE]:
      # 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, or manually mapped by us in PACKAGE_LICENSES
      if license_name in COPYRIGHT_ATTRIBUTION_LICENSES:
        # To limit needless efforts, if a package is BSD or GPL, we ignore BSD
        # and use GPL to avoid scanning the package, but we can only do this if
        # or_licenses_and_one_is_no_attribution has been set above.
        # This ensures that if we have License: || (BSD3 BSD4), we will
        # look in the source.
        if or_licenses_and_one_is_no_attribution:
          logging.info('%s: ignore license %s because ebuild LICENSES had %s',
                       self.fullnamerev, license_name,
                       ' '.join(ebuild_license_names))
        else:
          logging.info("%s: can't use %s, will scan source code for copyright",
                       self.fullnamerev, license_name)
          need_copyright_attribution = True
          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 sanity 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):
    """Save PackageInfo contents to a YAML file.

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

    Args:
      save_file: File to save the yaml contents into.
    """
    logging.debug('Saving license to %s', save_file)
    yaml_dump = list(self.__dict__.items())
    osutils.WriteFile(save_file, yaml.dump(yaml_dump), makedirs=True)


def _GetLicenseDirectories(board: Optional[str] = None,
                           sysroot: Optional[str] = None,
                           dir_set: str = _BOTH_DIRS,
                           buildroot: str = 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: (Typically) 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:
    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 _CheckForDeprecatedLicense(cpf, licenses):
  """See if |cpf| is a known package using a deprecated license.

  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.
  """
  # 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/exynos-pre-boot',
        '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(crbug.com/1111077): Remove this entirely.
  # We allow a few packages for now so new packages will stop showing up.
  if 'no-source-code' in licenses:
    # Note: DO NOT ADD ANY MORE PACKAGES HERE.
    LEGACY_PKGS = (
        'sys-firmware/dell-disk',
        'sys-firmware/dell-dock',
    )
    if not any(cpf.startswith(x) for x in LEGACY_PKGS):
      raise PackageLicenseError(
          f'{cpf}: no-source-code is not a valid license')

  # TODO(crbug.com/1019728): 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/android-flashstation-app',
        'chromeos-base/app-shell-apps-rialto',
        'chromeos-base/chromeos-board-default-apps-atlas',
        'chromeos-base/chromeos-board-default-apps-blaze',
        'chromeos-base/chromeos-board-default-apps-butterfly',
        'chromeos-base/chromeos-board-default-apps-candy',
        'chromeos-base/chromeos-board-default-apps-cave',
        'chromeos-base/chromeos-board-default-apps-chell',
        'chromeos-base/chromeos-board-default-apps-falco',
        'chromeos-base/chromeos-board-default-apps-kip',
        'chromeos-base/chromeos-board-default-apps-link',
        'chromeos-base/chromeos-board-default-apps-mickey',
        'chromeos-base/chromeos-board-default-apps-minnie',
        'chromeos-base/chromeos-board-default-apps-nocturne',
        'chromeos-base/chromeos-board-default-apps-paine',
        'chromeos-base/chromeos-board-default-apps-pi',
        'chromeos-base/chromeos-board-default-apps-pit',
        'chromeos-base/chromeos-board-default-apps-quawks',
        'chromeos-base/chromeos-board-default-apps-setzer',
        'chromeos-base/chromeos-board-default-apps-skate',
        'chromeos-base/chromeos-board-default-apps-snappy',
        'chromeos-base/chromeos-board-default-apps-soraka',
        'chromeos-base/chromeos-board-default-apps-speedy',
        'chromeos-base/chromeos-board-default-apps-squawks',
        'chromeos-base/chromeos-board-default-apps-terra',
        'chromeos-base/chromeos-board-default-apps-winky',
        'chromeos-base/chromeos-board-default-apps-yuna',
        'chromeos-base/chromeos-board-default-apps-zako',
        'chromeos-base/chromeos-bsp-trogdor-private',
        'chromeos-base/chromeos-chrome',
        'chromeos-base/chromeos-default-apps',
        'chromeos-base/chromeos-disk-firmware-enguarde',
        'chromeos-base/chromeos-disk-firmware-falco',
        'chromeos-base/chromeos-disk-firmware-gnawty',
        'chromeos-base/chromeos-disk-firmware-samus',
        'chromeos-base/chromeos-disk-firmware-squawks',
        'chromeos-base/chromeos-disk-firmware-test-enguarde',
        'chromeos-base/chromeos-disk-firmware-test-gnawty',
        'chromeos-base/chromeos-disk-firmware-test-samus',
        'chromeos-base/chromeos-disk-firmware-test-squawks',
        '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/rialto-cellular-autoconnect',
        'chromeos-base/rialto-modem-watchdog',
        'chromeos-base/rialto-override-apn',
        'chromeos-base/rialto-override-scanresponse',
        'chromeos-base/rialto-services',
        'chromeos-base/widevine-cdm',
        'dev-embedded/meta-embedded-toolkit',
        'dev-util/PVRPerfServer',
        'dev-util/PVRTrace',
        'media-libs/a630-fw',
        'media-libs/adreno-drivers',
        'media-libs/apl-hotword-support',
        'media-libs/arc-img-ddk',
        'media-libs/arc-mali-drivers',
        'media-libs/arc-mali-drivers-bifrost',
        'media-libs/dlm',
        '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/mfc-fw',
        'media-libs/mfc-fw-v7',
        'media-libs/mfc-fw-v8',
        'media-libs/rk3399-hotword-support',
        'media-libs/skl-hotword-support',
        'net-print/brother_mlaser',
        'sys-apps/accelerator-bootstrap',
        'sys-apps/eid',
        'sys-apps/loonix-hydrogen',
        'sys-boot/chromeos-firmware-ps8751',
        'sys-boot/chromeos-vendor-strings-wilco',
        'sys-boot/coreboot-private-files-amenia',
        'sys-boot/coreboot-private-files-aplrvp',
        'sys-boot/coreboot-private-files-atlas',
        'sys-boot/coreboot-private-files-baseboard-auron',
        'sys-boot/coreboot-private-files-baseboard-coral',
        'sys-boot/coreboot-private-files-baseboard-fizz',
        'sys-boot/coreboot-private-files-baseboard-glados',
        'sys-boot/coreboot-private-files-baseboard-jecht',
        'sys-boot/coreboot-private-files-baseboard-kalista',
        'sys-boot/coreboot-private-files-baseboard-kblrvp',
        'sys-boot/coreboot-private-files-baseboard-kunimitsu',
        'sys-boot/coreboot-private-files-baseboard-nami',
        'sys-boot/coreboot-private-files-baseboard-octopus',
        'sys-boot/coreboot-private-files-baseboard-poppy',
        'sys-boot/coreboot-private-files-baseboard-rammus',
        'sys-boot/coreboot-private-files-baseboard-reef',
        'sys-boot/coreboot-private-files-baseboard-strago',
        'sys-boot/coreboot-private-files-bolt',
        'sys-boot/coreboot-private-files-chipset-picasso',
        'sys-boot/coreboot-private-files-chipset-stnyridge',
        'sys-boot/coreboot-private-files-cnlrvp',
        'sys-boot/coreboot-private-files-drallion',
        'sys-boot/coreboot-private-files-eve',
        'sys-boot/coreboot-private-files-falco',
        'sys-boot/coreboot-private-files-fizz',
        'sys-boot/coreboot-private-files-glkrvp',
        'sys-boot/coreboot-private-files-grunt',
        'sys-boot/coreboot-private-files-hatch',
        'sys-boot/coreboot-private-files-kalista',
        'sys-boot/coreboot-private-files-mistral',
        'sys-boot/coreboot-private-files-nami',
        'sys-boot/coreboot-private-files-nautilus',
        'sys-boot/coreboot-private-files-nocturne',
        'sys-boot/coreboot-private-files-panther',
        'sys-boot/coreboot-private-files-peppy',
        'sys-boot/coreboot-private-files-poppy',
        'sys-boot/coreboot-private-files-pyro',
        'sys-boot/coreboot-private-files-rambi',
        'sys-boot/coreboot-private-files-rammus',
        'sys-boot/coreboot-private-files-reef',
        'sys-boot/coreboot-private-files-samus',
        'sys-boot/coreboot-private-files-sand',
        'sys-boot/coreboot-private-files-sarien',
        'sys-boot/coreboot-private-files-sklrvp',
        'sys-boot/coreboot-private-files-snappy',
        'sys-boot/coreboot-private-files-soraka',
        'sys-boot/amd-picasso-fsp',
        'sys-boot/exynos-pre-boot',
        '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',
        'www-servers/spacecast',
        'www-servers/ustreamer',
    }
    if not any(cpf.startswith(x) for x in LEGACY_PKGS):
      raise PackageLicenseError(f'{cpf}: Google-TOS is not a valid license.')


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

  def __init__(self, sysroot, package_fullnames, gen_licenses):
    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

    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):
    save_file = pkg.license_dump_path
    logging.debug('Getting license from %s for %s', save_file, pkg.name)
    yaml_dump = yaml.load(osutils.ReadFile(save_file))
    for key, value in yaml_dump:
      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):
    """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):
    """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.
    """
    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

      # 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)

        # 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)

  def AddExtraPkg(self, fullnamerev, homepages, license_names, license_texts):
    """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

    _CheckForDeprecatedLicense(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):
    """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

    Returns:
      str - license type

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

    # 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):
    """Read and return stock or cust license file specified in an ebuild."""
    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 a template with vars like {{foo}} using a dict of 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)
      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)
        raise 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)
        license_txt = self.ReadSharedLicense(sln, sysroot=self.sysroot)
        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 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):
    """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.
    """
    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)),
          'license_type': self.FindLicenseType(license_name,
                                               sysroot=self.sysroot),
          'license_packages': ' '.join(self.LicensedPackages(license_name)),
      }
      licenses_txt += [self.EvaluateTemplate(license_template, env)]

    file_template = ReadUnknownEncodedFile(output_template)
    tainted_warning = ''
    if 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' +
            '\n'.join(f'  <li>{x}</li>' for x in self.tainted_pkgs) +
            '\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),
    }
    osutils.WriteFile(output_file,
                      self.EvaluateTemplate(file_template, env).encode('utf-8'),
                      mode='wb')


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 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).output.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 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).output.splitlines()
    # Another option which we've decided not to use, is bdeps=n.  This outputs
    # just the packages we ship, but does 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 = []
    # [binary   R    ] x11-libs/libva-1.1.1 to /build/x86-alex/
    pkg_rgx = re.compile(r'\[[^]]+R[^]]+\] (.+) to /build/.*')
    # 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.
    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:
        raise AssertionError('Package incorrectly installed, try reinstalling',
                             '\n%s' % match2.group(1))

  return packages


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.

  Raises:
    Assertion error: if non-whitelisted illegal XML characters
      are found in the file.
    ValueError: returned if we get invalid XML.
  """
  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(u'[\x0c]')
  file_txt = silent_chars_re.sub('', file_txt)

  illegal_chars_re = re.compile(
      u'[\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):
  """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.
  """
  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)

  _CheckForDeprecatedLicense(fullnamerev, pkg.license_names)
  pkg.SaveLicenseDump(os.path.join(build_info_dir, 'license.yaml'))
