#  Copyright The ANGLE 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.
#
# Generates an Android.bp file from the json output of a 'gn desc' command.
# Example usage:
#   gn desc out/Android --format=json "*" > desc.json
#   python scripts/generate_android_bp.py desc.json > Android.bp

import json
import sys
import re
import os
import argparse

root_targets = [
    "//:libGLESv2",
    "//:libGLESv1_CM",
    "//:libEGL",
]

sdk_version = '28'
stl = 'libc++_static'

abi_arm = 'arm'
abi_arm64 = 'arm64'
abi_x86 = 'x86'
abi_x64 = 'x86_64'

abi_targets = [abi_arm, abi_arm64, abi_x86, abi_x64]


def tabs(indent):
    return ' ' * (indent * 4)


def has_child_values(value):
    # Elements of the blueprint can be pruned if they are empty lists or dictionaries of empty
    # lists
    if isinstance(value, list):
        return len(value) > 0
    if isinstance(value, dict):
        for (item, item_value) in value.items():
            if has_child_values(item_value):
                return True
        return False

    # This is a value leaf node
    return True


def write_blueprint_key_value(output, name, value, indent=1):
    if not has_child_values(value):
        return

    if isinstance(value, set) or isinstance(value, list):
        value = list(sorted(set(value)))

    if isinstance(value, list):
        output.append(tabs(indent) + '%s: [' % name)
        for item in value:
            output.append(tabs(indent + 1) + '"%s",' % item)
        output.append(tabs(indent) + '],')
        return
    if isinstance(value, dict):
        if not value:
            return
        output.append(tabs(indent) + '%s: {' % name)
        for (item, item_value) in value.items():
            write_blueprint_key_value(output, item, item_value, indent + 1)
        output.append(tabs(indent) + '},')
        return
    if isinstance(value, bool):
        output.append(tabs(indent) + '%s: %s,' % (name, 'true' if value else 'false'))
        return
    output.append(tabs(indent) + '%s: "%s",' % (name, value))


def write_blueprint(output, target_type, values):
    if target_type == 'license':
        comment = """
// Added automatically by a large-scale-change that took the approach of
// 'apply every license found to every target'. While this makes sure we respect
// every license restriction, it may not be entirely correct.
//
// e.g. GPL in an MIT project might only apply to the contrib/ directory.
//
// Please consider splitting the single license below into multiple licenses,
// taking care not to lose any license_kind information, and overriding the
// default license using the 'licenses: [...]' property on targets as needed.
//
// For unused files, consider creating a 'fileGroup' with "//visibility:private"
// to attach the license to, and including a comment whether the files may be
// used in the current project.
// See: http://go/android-license-faq"""
        output.append(comment)

    output.append('%s {' % target_type)
    for (key, value) in values.items():
        write_blueprint_key_value(output, key, value)
    output.append('}')


def gn_target_to_blueprint_target(target, target_info):
    if 'output_name' in target_info:
        return target_info['output_name']

    # Split the gn target name (in the form of //gn_file_path:target_name) into gn_file_path and
    # target_name
    target_regex = re.compile(r"^//([a-zA-Z0-9\-\+_/]*):([a-zA-Z0-9\-\+_.]+)$")
    match = re.match(target_regex, target)
    assert match is not None

    gn_file_path = match.group(1)
    target_name = match.group(2)
    assert len(target_name) > 0

    # Clean up the gn file path to be a valid blueprint target name.
    gn_file_path = gn_file_path.replace("/", "_").replace(".", "_").replace("-", "_")

    # Generate a blueprint target name by merging the gn path and target so each target is unique.
    # Prepend the 'angle' prefix to all targets in the root path (empty gn_file_path).
    # Skip this step if the target name already starts with 'angle' to avoid target names such as 'angle_angle_common'.
    root_prefix = "angle"
    if len(gn_file_path) == 0 and not target_name.startswith(root_prefix):
        gn_file_path = root_prefix

    # Avoid names such as _angle_common if the gn_file_path is empty.
    if len(gn_file_path) > 0:
        gn_file_path += "_"

    return gn_file_path + target_name


def remap_gn_path(path):
    # TODO: pass the gn gen folder as an arg so it is future proof. b/150457277
    remap_folders = [
        ('out/Android/gen/angle/', ''),
        ('out/Android/gen/', ''),
    ]

    remapped_path = path
    for (remap_source, remap_dest) in remap_folders:
        remapped_path = remapped_path.replace(remap_source, remap_dest)

    return remapped_path


def gn_path_to_blueprint_path(source):
    # gn uses '//' to indicate the root directory, blueprint uses the .bp file's location
    return remap_gn_path(re.sub(r'^//?', '', source))


def gn_paths_to_blueprint_paths(paths):
    rebased_paths = []
    for path in paths:
        rebased_paths.append(gn_path_to_blueprint_path(path))
    return rebased_paths


def gn_sources_to_blueprint_sources(sources):
    # Blueprints only list source files in the sources list. Headers are only referenced though
    # include paths.
    file_extension_allowlist = [
        '.c',
        '.cc',
        '.cpp',
    ]

    rebased_sources = []
    for source in sources:
        if os.path.splitext(source)[1] in file_extension_allowlist:
            rebased_sources.append(gn_path_to_blueprint_path(source))
    return rebased_sources


target_blockist = [
    '//build/config:shared_library_deps',
    '//third_party/vulkan-validation-layers/src:vulkan_clean_old_validation_layer_objects',
]

third_party_target_allowlist = [
    '//third_party/abseil-cpp',
    '//third_party/vulkan-deps',
    '//third_party/vulkan_memory_allocator',
    '//third_party/zlib',
]

include_blocklist = [
    '//buildtools/third_party/libc++/',
    '//out/Android/gen/third_party/vulkan-deps/glslang/src/include/',
    '//third_party/android_ndk/sources/android/cpufeatures/',
]


def gn_deps_to_blueprint_deps(target_info, build_info):
    static_libs = []
    shared_libs = []
    defaults = []
    generated_headers = []
    header_libs = []
    if 'deps' not in target_info:
        return static_libs, defaults

    for dep in target_info['deps']:
        if dep not in target_blockist and (not dep.startswith('//third_party') or any(
                dep.startswith(substring) for substring in third_party_target_allowlist)):
            dep_info = build_info[dep]
            blueprint_dep_name = gn_target_to_blueprint_target(dep, dep_info)

            # Depending on the dep type, blueprints reference it differently.
            gn_dep_type = dep_info['type']
            if gn_dep_type == 'static_library':
                static_libs.append(blueprint_dep_name)
            elif gn_dep_type == 'shared_library':
                shared_libs.append(blueprint_dep_name)
            elif gn_dep_type == 'source_set' or gn_dep_type == 'group':
                defaults.append(blueprint_dep_name)
            elif gn_dep_type == 'action':
                generated_headers.append(blueprint_dep_name)

            # Blueprints do not chain linking of static libraries.
            (child_static_libs, _, _, child_generated_headers, _) = gn_deps_to_blueprint_deps(
                dep_info, build_info)

            # Each target needs to link all child static library dependencies.
            static_libs += child_static_libs

            # Each blueprint target runs genrules in a different output directory unlike GN. If a
            # target depends on another's genrule, it wont find the outputs. Propogate generated
            # headers up the dependency stack.
            generated_headers += child_generated_headers
        elif dep == '//third_party/android_ndk:cpu_features':
            # chrome_zlib needs cpufeatures from the Android NDK. Rather than including the
            # entire NDK is a dep in the ANGLE checkout, use the library that's already part
            # of Android.
            dep_info = build_info[dep]
            blueprint_dep_name = gn_target_to_blueprint_target(dep, dep_info)
            static_libs.append('cpufeatures')

    return static_libs, shared_libs, defaults, generated_headers, header_libs


def gn_libs_to_blueprint_shared_libraries(target_info):
    lib_blockist = [
        'android_support',
        'unwind',
    ]

    result = []
    if 'libs' in target_info:
        for lib in target_info['libs']:
            if lib not in lib_blockist:
                android_lib = lib if '@' in lib else 'lib' + lib
                result.append(android_lib)
    return result


def gn_include_dirs_to_blueprint_include_dirs(target_info):
    result = []
    if 'include_dirs' in target_info:
        for include_dir in target_info['include_dirs']:
            if len(include_dir) > 0 and include_dir not in include_blocklist:
                result.append(gn_path_to_blueprint_path(include_dir))
    return result


def escape_quotes(string):
    return string.replace("\"", "\\\"").replace("\'", "\\\'")


def gn_cflags_to_blueprint_cflags(target_info):
    result = []

    # regexs of allowlisted cflags
    cflag_allowlist = [
        r'^-Wno-.*$',  # forward cflags that disable warnings
        r'-mpclmul'  # forward "-mpclmul" (used by zlib)
    ]

    for cflag_type in ['cflags', 'cflags_c', 'cflags_cc']:
        if cflag_type in target_info:
            for cflag in target_info[cflag_type]:
                for allowlisted_cflag in cflag_allowlist:
                    if re.search(allowlisted_cflag, cflag):
                        result.append(cflag)

    # Chrome and Android use different versions of Clang which support differnt warning options.
    # Ignore errors about unrecognized warning flags.
    result.append('-Wno-unknown-warning-option')

    # Override AOSP build flags to match ANGLE's CQ testing and reduce binary size
    result.append('-Os')
    result.append('-fno-unwind-tables')

    if 'defines' in target_info:
        for define in target_info['defines']:
            # Don't emit ANGLE's CPU-bits define here, it will be part of the arch-specific
            # information later
            result.append('-D%s' % escape_quotes(define))

    return result


blueprint_library_target_types = {
    "static_library": "cc_library_static",
    "shared_library": "cc_library_shared",
    "source_set": "cc_defaults",
    "group": "cc_defaults",
}


def merge_bps(bps_for_abis):
    common_bp = {}
    for abi in abi_targets:
        for key in bps_for_abis[abi]:
            if isinstance(bps_for_abis[abi][key], list):
                # Find list values that are common to all ABIs
                for value in bps_for_abis[abi][key]:
                    value_in_all_abis = True
                    for abi2 in abi_targets:
                        if key == 'defaults':
                            # arch-specific defaults are not supported
                            break
                        value_in_all_abis = value_in_all_abis and (key in bps_for_abis[abi2].keys(
                        )) and (value in bps_for_abis[abi2][key])
                    if value_in_all_abis:
                        if key in common_bp.keys():
                            common_bp[key].append(value)
                        else:
                            common_bp[key] = [value]
                    else:
                        if 'arch' not in common_bp.keys():
                            # Make sure there is an 'arch' entry to hold ABI-specific values
                            common_bp['arch'] = {}
                            for abi3 in abi_targets:
                                common_bp['arch'][abi3] = {}
                        if key in common_bp['arch'][abi].keys():
                            common_bp['arch'][abi][key].append(value)
                        else:
                            common_bp['arch'][abi][key] = [value]
            else:
                # Assume everything that's not a list is common to all ABIs
                common_bp[key] = bps_for_abis[abi][key]

    return common_bp


def library_target_to_blueprint(target, build_info):
    bps_for_abis = {}
    blueprint_type = ""
    for abi in abi_targets:
        if target not in build_info[abi].keys():
            bps_for_abis[abi] = {}
            continue

        target_info = build_info[abi][target]

        blueprint_type = blueprint_library_target_types[target_info['type']]

        bp = {'name': gn_target_to_blueprint_target(target, target_info)}

        if 'sources' in target_info:
            bp['srcs'] = gn_sources_to_blueprint_sources(target_info['sources'])

        (bp['static_libs'], bp['shared_libs'], bp['defaults'], bp['generated_headers'],
         bp['header_libs']) = gn_deps_to_blueprint_deps(target_info, build_info[abi])
        bp['shared_libs'] += gn_libs_to_blueprint_shared_libraries(target_info)

        bp['local_include_dirs'] = gn_include_dirs_to_blueprint_include_dirs(target_info)

        bp['cflags'] = gn_cflags_to_blueprint_cflags(target_info)

        bp['sdk_version'] = sdk_version
        bp['stl'] = stl
        if target in root_targets:
            bp['vendor'] = True
            bp['target'] = {'android': {'relative_install_path': 'egl'}}
        bps_for_abis[abi] = bp

    common_bp = merge_bps(bps_for_abis)

    return blueprint_type, common_bp


def gn_action_args_to_blueprint_args(blueprint_inputs, blueprint_outputs, args):
    # TODO: pass the gn gen folder as an arg so we know how to get from the gen path to the root
    # path. b/150457277
    remap_folders = [
        # Specific special-cases first, since the other will strip the prefixes.
        ('gen/third_party/vulkan-deps/glslang/src/include/glslang/build_info.h',
         'glslang/build_info.h'),
        ('third_party/vulkan-deps/glslang/src',
         'external/angle/third_party/vulkan-deps/glslang/src'),
        ('../../', ''),
        ('gen/', ''),
    ]

    result_args = []
    for arg in args:
        # Attempt to find if this arg is a path to one of the inputs. If it is, use the blueprint
        # $(location <path>) argument instead so the path gets remapped properly to the location
        # that the script is run from
        remapped_path_arg = arg
        for (remap_source, remap_dest) in remap_folders:
            remapped_path_arg = remapped_path_arg.replace(remap_source, remap_dest)

        if remapped_path_arg in blueprint_inputs or remapped_path_arg in blueprint_outputs:
            result_args.append('$(location %s)' % remapped_path_arg)
        elif os.path.basename(remapped_path_arg) in blueprint_outputs:
            result_args.append('$(location %s)' % os.path.basename(remapped_path_arg))
        else:
            result_args.append(remapped_path_arg)

    return result_args


blueprint_gen_types = {
    "action": "cc_genrule",
}


inputs_blocklist = [
    '//.git/HEAD',
]

outputs_remap = {
    'build_info.h': 'glslang/build_info.h',
}


def is_input_in_tool_files(tool_files, input):
    return input in tool_files


def action_target_to_blueprint(target, build_info):
    target_info = build_info[target]
    blueprint_type = blueprint_gen_types[target_info['type']]

    bp = {'name': gn_target_to_blueprint_target(target, target_info)}

    # Blueprints use only one 'srcs', merge all gn inputs into one list.
    gn_inputs = []
    if 'inputs' in target_info:
        for input in target_info['inputs']:
            if input not in inputs_blocklist:
                gn_inputs.append(input)
    if 'sources' in target_info:
        gn_inputs += target_info['sources']
    # Filter out the 'script' entry since Android.bp doesn't like the duplicate entries
    if 'script' in target_info:
        gn_inputs = [
            input for input in gn_inputs
            if not is_input_in_tool_files(target_info['script'], input)
        ]
    bp_srcs = gn_paths_to_blueprint_paths(gn_inputs)

    bp['srcs'] = bp_srcs

    # genrules generate the output right into the 'root' directory. Strip any path before the
    # file name.
    bp_outputs = []
    for gn_output in target_info['outputs']:
        output = os.path.basename(gn_output)
        if output in outputs_remap.keys():
            output = outputs_remap[output]
        bp_outputs.append(output)

    bp['out'] = bp_outputs

    bp['tool_files'] = [gn_path_to_blueprint_path(target_info['script'])]

    # Generate the full command, $(location) refers to tool_files[0], the script
    cmd = ['$(location)'] + gn_action_args_to_blueprint_args(bp_srcs, bp_outputs,
                                                             target_info['args'])
    bp['cmd'] = ' '.join(cmd)

    bp['sdk_version'] = sdk_version

    return blueprint_type, bp


def gn_target_to_blueprint(target, build_info):
    for abi in abi_targets:
        gn_type = build_info[abi][target]['type']
        if gn_type in blueprint_library_target_types:
            return library_target_to_blueprint(target, build_info)
        elif gn_type in blueprint_gen_types:
            return action_target_to_blueprint(target, build_info[abi])
        else:
            # Target is not used by this ABI
            continue


def get_gn_target_dependencies(output_dependencies, build_info, target):
    if target not in output_dependencies:
        output_dependencies.insert(0, target)

    for dep in build_info[target]['deps']:
        if dep in target_blockist:
            # Blocklisted dep
            continue
        if dep not in build_info:
            # No info for this dep, skip it
            continue

        # Recurse
        get_gn_target_dependencies(output_dependencies, build_info, dep)


def main():
    parser = argparse.ArgumentParser(
        description='Generate Android blueprints from gn descriptions.')

    for abi in abi_targets:
        fixed_abi = abi
        if abi == abi_x64:
            fixed_abi = 'x64'  # gn uses x64, rather than x86_64
        parser.add_argument(
            'gn_json_' + fixed_abi,
            help=fixed_abi +
            'gn desc in json format. Generated with \'gn desc <out_dir> --format=json "*"\'.')
    args = vars(parser.parse_args())

    build_info = {}
    for abi in abi_targets:
        fixed_abi = abi
        if abi == abi_x64:
            fixed_abi = 'x64'  # gn uses x64, rather than x86_64
        with open(args['gn_json_' + fixed_abi], 'r') as f:
            build_info[abi] = json.load(f)

    targets_to_write = []
    for abi in abi_targets:
        for root_target in root_targets:
            get_gn_target_dependencies(targets_to_write, build_info[abi], root_target)

    blueprint_targets = []
    for target in targets_to_write:
        blueprint_targets.append(gn_target_to_blueprint(target, build_info))

    # Add license build rules
    blueprint_targets.append(('package', {
        'default_applicable_licenses': ['external_angle_license'],
    }))
    blueprint_targets.append(('license', {
        'name':
            'external_angle_license',
        'visibility': [':__subpackages__'],
        'license_kinds': [
            'SPDX-license-identifier-Apache-2.0',
            'SPDX-license-identifier-BSD',
            'SPDX-license-identifier-GPL',
            'SPDX-license-identifier-GPL-2.0',
            'SPDX-license-identifier-GPL-3.0',
            'SPDX-license-identifier-LGPL',
            'SPDX-license-identifier-MIT',
            'SPDX-license-identifier-Zlib',
            'legacy_unencumbered',
        ],
        'license_text': [
            'LICENSE',
            'src/common/third_party/smhasher/LICENSE',
            'src/common/third_party/xxhash/LICENSE',
            'src/libANGLE/renderer/vulkan/shaders/src/third_party/ffx_spd/LICENSE',
            'src/tests/test_utils/third_party/LICENSE',
            'src/third_party/libXNVCtrl/LICENSE',
            'src/third_party/volk/LICENSE.md',
            'third_party/abseil-cpp/LICENSE',
            'third_party/android_system_sdk/LICENSE',
            'third_party/bazel/LICENSE',
            'third_party/colorama/LICENSE',
            'third_party/proguard/LICENSE',
            'third_party/r8/LICENSE',
            'third_party/turbine/LICENSE',
            'third_party/vulkan-deps/glslang/LICENSE',
            'third_party/vulkan-deps/glslang/src/LICENSE.txt',
            'third_party/vulkan-deps/LICENSE',
            'third_party/vulkan-deps/spirv-headers/LICENSE',
            'third_party/vulkan-deps/spirv-headers/src/LICENSE',
            'third_party/vulkan-deps/spirv-tools/LICENSE',
            'third_party/vulkan-deps/spirv-tools/src/LICENSE',
            'third_party/vulkan-deps/spirv-tools/src/utils/vscode/src/lsp/LICENSE',
            'third_party/vulkan-deps/vulkan-headers/LICENSE.txt',
            'third_party/vulkan-deps/vulkan-headers/src/LICENSE.txt',
            'third_party/vulkan_memory_allocator/LICENSE.txt',
            'third_party/zlib/LICENSE',
            'tools/flex-bison/third_party/m4sugar/LICENSE',
            'tools/flex-bison/third_party/skeletons/LICENSE',
            'util/windows/third_party/StackWalker/LICENSE',
        ],
    }))

    # Add APKs with all of the root libraries
    blueprint_targets.append((
        'filegroup',
        {
            'name': 'ANGLE_srcs',
            # Only add EmptyMainActivity.java since we just need to be able to reply to the intent
            # android.app.action.ANGLE_FOR_ANDROID to indicate ANGLE is present on the device.
            'srcs': ['src/android_system_settings/src/com/android/angle/EmptyMainActivity.java'],
        }))
    blueprint_targets.append((
        'java_defaults',
        {
            'name': 'ANGLE_java_defaults',
            'sdk_version': 'system_current',
            'min_sdk_version': sdk_version,
            'compile_multilib': 'both',
            'use_embedded_native_libs': True,
            'jni_libs': [
                # hack: assume abi_arm
                gn_target_to_blueprint_target(target, build_info[abi_arm][target])
                for target in root_targets
            ],
            'aaptflags': [
                # Don't compress *.json files
                '-0 .json',
            ],
            'srcs': [':ANGLE_srcs'],
            'plugins': ['java_api_finder',],
            'privileged': True,
            'product_specific': True,
            'owner': 'google',
        }))

    blueprint_targets.append(('android_app', {
        'name': 'ANGLE',
        'defaults': ['ANGLE_java_defaults'],
        'manifest': 'android/AndroidManifest.xml',
        'asset_dirs': ['src/android_system_settings/assets',],
    }))

    output = [
        """// GENERATED FILE - DO NOT EDIT.
// Generated by %s
//
// Copyright 2020 The ANGLE 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.
//
""" % sys.argv[0]
    ]
    for (blueprint_type, blueprint_data) in blueprint_targets:
        write_blueprint(output, blueprint_type, blueprint_data)

    print('\n'.join(output))


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