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

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