# -*- 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(board, all_packages, generateMissing, packages):
  """Do the work when we're not called as a hook."""
  logging.info('Using board %s.', board)

  builddir = os.path.join(cros_build_lib.GetSysroot(board=board),
                          'tmp', 'portage')

  if not os.path.exists(builddir):
    raise AssertionError(
        'FATAL: %s missing.\n'
        'Did you give the right board and build that tree?' % builddir)

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

  if not packages:
    raise AssertionError('FATAL: Could not get any packages for board %s' %
                         board)

  logging.debug('Initial Package list to work through:\n%s',
                '\n'.join(sorted(packages)))
  licensing = licenses_lib.Licensing(board, 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 main(args):
  parser = commandline.ArgumentParser(usage=__doc__)
  parser.add_argument('-b', '--board',
                      help='which board to run for, like x86-alex')
  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')
  opts = parser.parse_args(args)


  if not opts.board:
    raise AssertionError('No board given (--board)')

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

  if opts.gen_licenses and os.geteuid() != 0:
    raise AssertionError('Run with sudo if you use --generate-licenses.')

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

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