# -*- 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
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 )"
    '(',
    '||',
]

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

    self.ebuild_path = 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:
      self.ebuild_path = self._FindEbuildPath()
      self._RunEbuildPhases(self.ebuild_path, ['clean', 'fetch'])
      raw_output = self._RunEbuildPhases(self.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 AssertCorrectness(self, build_info_dir, ebuild_path):
    """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):
    """_AssertMetapackageNoContent 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):
    """_AssertVirtualIsMetapackage 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: 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/sc7280-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)
        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)

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

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