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