#!/usr/bin/env vpython3

#  Copyright 2016 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.
"""Generates license markdown for a prebuilt version of WebRTC.

Licenses are taken from dependent libraries which are determined by
GN desc command `gn desc` on all targets specified via `--target` argument.

One can see all dependencies by invoking this command:
$ gn.py desc --all --format=json <out_directory> <target> | \
        vpython3 -m json.tool
(see "deps" subarray)

Libraries are mapped to licenses via LIB_TO_LICENSES_DICT dictionary.

"""

import sys
import argparse
import json
import logging
import os
import re
import subprocess
from html import escape

# Third_party library to licences mapping. Keys are names of the libraries
# (right after the `third_party/` prefix)
LIB_TO_LICENSES_DICT = {
    'abseil-cpp': ['third_party/abseil-cpp/LICENSE'],
    'android_sdk': ['third_party/android_sdk/LICENSE'],
    'android_toolchain': ['third_party/android_toolchain/NOTICE'],
    'auto': [
        'third_party/android_deps/libs/'
        'com_google_auto_service_auto_service/LICENSE'
    ],
    'boringssl': ['third_party/boringssl/src/LICENSE'],
    'crc32c': ['third_party/crc32c/src/LICENSE'],
    'compiler-rt': ['third_party/compiler-rt/src/LICENSE.TXT'],
    'cpu_features': ['third_party/cpu_features/src/LICENSE'],
    'dav1d': ['third_party/dav1d/LICENSE'],
    'errorprone': [
        'third_party/android_deps/libs/'
        'com_google_errorprone_error_prone_core/LICENSE'
    ],
    'fiat': ['third_party/boringssl/src/third_party/fiat/LICENSE'],
    'guava': ['third_party/android_deps/libs/com_google_guava_guava/LICENSE'],
    'ijar': ['third_party/ijar/LICENSE'],
    'jsoncpp': ['third_party/jsoncpp/LICENSE'],
    'libaom': ['third_party/libaom/source/libaom/LICENSE'],
    'libc++': ['third_party/libc++/src/LICENSE.TXT'],
    'libc++abi': ['third_party/libc++abi/src/LICENSE.TXT'],
    'libjpeg_turbo': ['third_party/libjpeg_turbo/LICENSE.md'],
    'libsrtp': ['third_party/libsrtp/LICENSE'],
    'libunwind': ['third_party/libunwind/src/LICENSE.TXT'],
    'libvpx': ['third_party/libvpx/source/libvpx/LICENSE'],
    'libyuv': ['third_party/libyuv/LICENSE'],
    'llvm-libc': ['third_party/llvm-libc/src/LICENSE.TXT'],
    'nasm': ['third_party/nasm/LICENSE'],
    'opus': ['third_party/opus/src/COPYING'],
    'pffft': ['third_party/pffft/LICENSE'],
    'protobuf': ['third_party/protobuf/LICENSE'],
    'rnnoise': ['third_party/rnnoise/COPYING'],
    'sframe': ['third_party/sframe/src/LICENSE'],
    'webrtc': ['LICENSE'],
    'zlib': ['third_party/zlib/LICENSE'],
    'base64': ['rtc_base/third_party/base64/LICENSE'],
    'fft': ['modules/third_party/fft/LICENSE'],
    'g711': ['modules/third_party/g711/LICENSE'],
    'g722': ['modules/third_party/g722/LICENSE'],
    'ooura': ['common_audio/third_party/ooura/LICENSE'],
    'spl_sqrt_floor': ['common_audio/third_party/spl_sqrt_floor/LICENSE'],
    'kotlin_stdlib': ['third_party/kotlin_stdlib/LICENSE'],
    'jni_zero': ['third_party/jni_zero/LICENSE'],
    'protobuf-javascript': ['third_party/protobuf-javascript/LICENSE'],
    'perfetto': ['third_party/perfetto/LICENSE'],
    'rust_stdlib': [
        'third_party/rust-toolchain/share/doc/rustc/licenses/Apache-2.0.txt',
        'third_party/rust-toolchain/share/doc/rustc/licenses/MIT.txt',
    ],
    'rust/cxx/v1':
    ['third_party/rust/chromium_crates_io/vendor/cxx-v1/LICENSE-APACHE'],
    'rust/foldhash/v0_2':
    ['third_party/rust/chromium_crates_io/vendor/foldhash-v0_2/LICENSE'],

    # These are not libraries but collections of libraries.
    'android_deps': [],
    'androidx': [],

    # Compile time dependencies, no license needed:
    'ow2_asm': [],
    'jdk': [],

    # Compile-time Rust proc-macro crates, no license needed in binary:
    'rust/cxxbridge_macro/v1': []
}

# Third_party library _regex_ to licences mapping. Keys are regular expression
# with names of the libraries (right after the `third_party/` prefix)
LIB_REGEX_TO_LICENSES_DICT = {
    'android_deps:android_support_annotations.*': [
        'third_party/android_deps/libs/' +
        'com_android_support_support_annotations/LICENSE'
    ],

    'android_build_tools.*': [
        'third_party/android_build_tools/bundletool/LICENSE'
    ],

    # Internal dependencies, licenses are already included by other deps.
    'android_deps:com_android_support_support_annotations.*': [],
}


SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
WEBRTC_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))
SRC_DIR = os.path.dirname(os.path.dirname(SCRIPT_DIR))

# Chromium, and potentially other repositories, embed us in the location
# "//third_party/webrtc". When this is the case, we expect that some of the
# tools we need are *actually* in their build folder, thus we need to move up
# to the *true* source root, when we're embedded like this.
if SRC_DIR.endswith(os.path.join('third_party', 'webrtc')):
    SRC_DIR = os.path.abspath(os.path.join(SRC_DIR, os.pardir, os.pardir))
sys.path.append(os.path.join(SRC_DIR, 'build'))
import find_depot_tools

THIRD_PARTY_LIB_SIMPLE_NAME_REGEX = re.compile(
    r'^.*/third_party/(rust/\w+/\w+|[\w\-+]+).*$')
THIRD_PARTY_LIB_REGEX_TEMPLATE = r'^.*/third_party/%s$'
RUST_HOST_BUILD_TOOLS_REGEX = re.compile(
    r'\(//build/toolchain/.*_for_rust_host_build_tools\)$')


class LicenseBuilder:

    def __init__(self,
                 buildfile_dirs,
                 targets,
                 lib_to_licenses_dict=None,
                 lib_regex_to_licenses_dict=None):
        if lib_to_licenses_dict is None:
            lib_to_licenses_dict = LIB_TO_LICENSES_DICT

        if lib_regex_to_licenses_dict is None:
            lib_regex_to_licenses_dict = LIB_REGEX_TO_LICENSES_DICT

        self.buildfile_dirs = buildfile_dirs
        self.targets = targets
        self.lib_to_licenses_dict = lib_to_licenses_dict
        self.lib_regex_to_licenses_dict = lib_regex_to_licenses_dict

        self.common_licenses_dict = self.lib_to_licenses_dict.copy()
        self.common_licenses_dict.update(self.lib_regex_to_licenses_dict)

    @staticmethod
    def _parse_library_name(dep):
        """Returns library name after third_party

    Input one of:
    //a/b/third_party/libname:c
    //a/b/third_party/libname:c(//d/e/f:g)
    //a/b/third_party/libname/c:d(//e/f/g:h)

    Outputs libname or None if this is not a third_party dependency.
    """
        groups = THIRD_PARTY_LIB_SIMPLE_NAME_REGEX.match(dep)
        return groups.group(1) if groups else None

    def _parse_library(self, dep):
        """Return library simple or regex name matching `dep` after third_party

    This method matches `dep` dependency against simple names in
    LIB_TO_LICENSES_DICT and regular expression names in
    LIB_REGEX_TO_LICENSES_DICT keys

    Outputs matched dict key or None if this is not a third_party dependency.
    """
        if RUST_HOST_BUILD_TOOLS_REGEX.search(dep):
            return None
        if dep.startswith('//build/rust/std:'):
            return 'rust_stdlib'

        libname = LicenseBuilder._parse_library_name(dep)

        for lib_regex in self.lib_regex_to_licenses_dict:
            if re.match(THIRD_PARTY_LIB_REGEX_TEMPLATE % lib_regex, dep):
                return lib_regex

        return libname

    @staticmethod
    def _run_gn(buildfile_dir, target):
        cmd = [
            sys.executable,
            os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'),
            'desc',
            '--all',
            '--format=json',
            os.path.abspath(buildfile_dir),
            target,
        ]
        logging.debug('Running: %r', cmd)
        output_json = subprocess.check_output(cmd,
                                              cwd=WEBRTC_ROOT).decode('UTF-8')
        logging.debug('Output: %s', output_json)
        return output_json

    def _get_third_party_libraries(self, buildfile_dir, target):
        license_json = LicenseBuilder._run_gn(buildfile_dir, target)
        try:
            output = json.loads(license_json)
        except:
            logging.error("unable to parse license_json = '%s'", license_json)
            raise
        libraries = set()
        for described_target in list(output.values()):
            third_party_libs = (self._parse_library(dep)
                                for dep in described_target['deps'])
            libraries |= set(lib for lib in third_party_libs if lib)
        return libraries

    def generate_license_text(self, output_dir):
        # Get a list of third_party libs from gn. For fat libraries we must
        # consider all architectures, hence the multiple buildfile directories.
        third_party_libs = set()
        for buildfile in self.buildfile_dirs:
            for target in self.targets:
                third_party_libs |= self._get_third_party_libraries(
                    buildfile, target)
        assert len(third_party_libs) > 0

        missing_licenses = third_party_libs - set(
            self.common_licenses_dict.keys())
        if missing_licenses:
            error_msg = 'Missing licenses for third_party targets: %s' % \
                        ', '.join(sorted(missing_licenses))
            logging.error(error_msg)
            raise Exception(error_msg)

        # Put webrtc at the front of the list.
        license_libs = sorted(third_party_libs)
        license_libs.insert(0, 'webrtc')

        logging.info('List of licenses: %s', ', '.join(license_libs))

        # Generate markdown.
        output_license_file = open(os.path.join(output_dir, 'LICENSE.md'),
                                   'w+')
        for license_lib in license_libs:
            if len(self.common_licenses_dict[license_lib]) == 0:
                logging.info(
                    'Skipping compile time or internal dependency: %s',
                    license_lib)
                continue  # Compile time dependency

            output_license_file.write('# %s\n' % license_lib)
            output_license_file.write('```\n')
            for path in self.common_licenses_dict[license_lib]:
                license_path = os.path.join(WEBRTC_ROOT, path)
                with open(license_path, 'r') as license_file:
                    license_text = escape(license_file.read(), quote=True)
                    output_license_file.write(license_text)
                    output_license_file.write('\n')
            output_license_file.write('```\n\n')

        output_license_file.close()


def main():
    parser = argparse.ArgumentParser(description='Generate WebRTC LICENSE.md')
    parser.add_argument('--verbose',
                        action='store_true',
                        default=False,
                        help='Debug logging.')
    parser.add_argument('--target',
                        required=True,
                        action='append',
                        default=[],
                        help='Name of the GN target to generate a license for')
    parser.add_argument('output_dir',
                        help='Directory to output LICENSE.md to.')
    parser.add_argument('buildfile_dirs',
                        nargs='+',
                        help='Directories containing gn generated ninja files')
    args = parser.parse_args()

    logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO)

    builder = LicenseBuilder(args.buildfile_dirs, args.target)
    builder.generate_license_text(args.output_dir)


if __name__ == '__main__':
    sys.exit(main())
