# -*- coding: utf-8 -*-
# Copyright (c) 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.

"""Generate an HTML file containing license info for all installed packages.

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

End user (i.e. package owners) documentation is here:
https://dev.chromium.org/chromium-os/licensing/licensing-for-chromiumos-package-owners

Usage:
For this script to work, you must have built the architecture
this is being run against, _after_ you've last run repo sync.
Otherwise, it will query newer source code and then fail to work on packages
that are out of date in your build.

Recommended build:
  cros_sdk
  export BOARD=x86-alex
  sudo rm -rf /build/$BOARD
  cd ~/trunk/src/scripts
  # If you wonder why we need to build Chromium OS just to run
  # `emerge -p -v virtual/target-os` on it, we don't.
  # However, later we run ebuild unpack, and this will apply patches and run
  # configure. Configure will fail due to aclocal macros missing in
  # /build/x86-alex/usr/share/aclocal (those are generated during build).
  # This will take about 10mn on a Z620.
  ./build_packages --board=$BOARD --nowithautotest --nowithtest --nowithdev \
                   --nowithfactory
  cd ~/trunk/chromite/licensing
  # This removes left over packages from an earlier build that could cause
  # conflicts.
  eclean-$BOARD packages
  %(prog)s [--debug] [--all-packages] --board $BOARD [-o o.html] 2>&1 | tee out

The workflow above is what you would do to generate a licensing file by hand
given a chromeos tree.
Note that building packages now creates a license.yaml fork in the package
which you can see with
qtbz2 -x -O  /build/x86-alex/packages/dev-util/libc-bench-0.0.1-r8.tbz2 |
     qxpak -x -O - license.yaml
This gets automatically installed in
/build/x86-alex/var/db/pkg/dev-util/libc-bench-0.0.1-r8/license.yaml

Unless you run with --generate-licenses, the script will now gather those
license bits and generate a license file from there.
License bits for each package are generated by default from
src/scripts/hooks/install/gen-package-licenses.sh which gets run automatically
by emerge as part of a package build (by running this script with
--hook /path/to/tmp/portage/build/tree/for/that/package

If license bits are missing, they are generated on the fly if you were running
with sudo. If you didn't use sudo, this on the fly late generation will fail
and act as a warning that your prebuilts were missing package build time
licenses.

You can check the licenses and/or generate a HTML file for a list of
packages using --package or -p:
  %(prog)s --package "dev-libs/libatomic_ops-7.2d" --package \
  "net-misc/wget-1.14" --board $BOARD -o out.html

Note that you'll want to use --generate-licenses to force regeneration of the
licensing bits from a package source you may have just modified but not rebuilt.

If you want to check licensing against all ChromeOS packages, you should
run ./build_packages --board=$BOARD to build everything and then run
this script with --all-packages.

By default, when no package is specified, this script processes all
packages for $BOARD.
"""

from __future__ import print_function

import os

from chromite.lib import build_target_lib
from chromite.lib import commandline
from chromite.lib import cros_logging as logging
from chromite.lib import osutils

from chromite.licensing import licenses_lib


EXTRA_LICENSES_DIR = os.path.join(licenses_lib.SCRIPT_DIR,
                                  'extra_package_licenses')

# These packages exist as workarounds....
EXTRA_PACKAGES = (
    ('sys-kernel/Linux-2.6',
     ['http://www.kernel.org/'], ['GPL-2'], []),
)


def LoadPackageInfo(sysroot, all_packages, generateMissing, packages):
  """Do the work when we're not called as a hook."""
  logging.info('Processing sysroot %s', sysroot)

  detect_packages = not packages
  if detect_packages:
    # If no packages were specified, we look up the full list.
    packages = licenses_lib.ListInstalledPackages(sysroot, all_packages)

  assert packages, f'{sysroot}: could not find any packages'

  logging.debug('Initial Package list to work through:\n%s',
                '\n'.join(sorted(packages)))
  licensing = licenses_lib.Licensing(sysroot, packages, generateMissing)

  licensing.LoadPackageInfo()
  logging.debug('Package list to skip:\n%s',
                '\n'.join([p for p in sorted(packages)
                           if licensing.packages[p].skip]))
  logging.debug('Package list left to work through:\n%s',
                '\n'.join([p for p in sorted(packages)
                           if not licensing.packages[p].skip]))
  licensing.ProcessPackageLicenses()
  if detect_packages:
    # If we detected 'all' packages, we have to add in these extras.
    for fullnamewithrev, homepages, names, files in EXTRA_PACKAGES:
      license_texts = [osutils.ReadFile(os.path.join(EXTRA_LICENSES_DIR, f))
                       for f in files]
      licensing.AddExtraPkg(fullnamewithrev, homepages, names, license_texts)

  return licensing


def get_parser() -> commandline.ArgumentParser:
  """Return a command line parser."""
  parser = commandline.ArgumentParser(usage=__doc__)

  group = parser.add_mutually_exclusive_group(required=True)
  group.add_argument('-b', '--board',
                     help='which board to run for, like x86-alex')
  group.add_argument('--sysroot', type='path',
                     help='which sysroot to run on (e.g. /build/eve)')

  parser.add_argument('-p', '--package', action='append', default=[],
                      dest='packages',
                      help='check the license of the package, e.g.,'
                      'dev-libs/libatomic_ops-7.2d')
  parser.add_argument('-a', '--all-packages', action='store_true',
                      dest='all_packages',
                      help='Run licensing against all packages in the '
                      'build tree, instead of just virtual/target-os '
                      'dependencies.')
  parser.add_argument('-g', '--generate-licenses', action='store_true',
                      dest='gen_licenses',
                      help='Generate license information, if missing.')
  parser.add_argument('-o', '--output', type='path',
                      help='which html file to create with output')
  return parser


def main(args):
  parser = get_parser()
  opts = parser.parse_args(args)

  if not opts.output and not opts.gen_licenses:
    parser.error('You must specify --output and/or --generate-licenses')

  sysroot = (opts.sysroot or
             build_target_lib.get_default_sysroot_path(opts.board))

  licensing = LoadPackageInfo(
      sysroot, opts.all_packages, opts.gen_licenses, opts.packages)

  if opts.output:
    licensing.GenerateHTMLLicenseOutput(opts.output)
