# -*- 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, 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 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 commandline
from chromite.lib import cros_build_lib
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 cros_build_lib.GetSysroot(opts.board)

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

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