#  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 4 'gn desc' commands.
# Invoked during Skia rolls by roll_aosp.sh. For local testing, see:
#  scripts/roll_aosp.sh --genAndroidBp

import json
import sys
import re
import os
import argparse
import functools
import collections
import textwrap
from typing import List, Tuple

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

END2END_TEST_TARGET = "//src/tests:angle_end2end_tests__library"

# Used only in generated Android.bp file for DMA-BUF-enabled builds on Android.
# See b/353262025 for details.
DMA_BUF_TARGET = "//src/libANGLE/renderer/vulkan:angle_android_vulkan_dma_buf"

BLUEPRINT_COMMENT_PROPERTY = '__android_bp_comment'

CURRENT_SDK_VERSION = 'current'
MIN_SDK_VERSION = '28'
TARGET_SDK_VERSION = '37'
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]

rust_ffi_gen_output_map = {}


def gn_abi(abi):
    # gn uses x64, rather than x86_64
    return 'x64' if abi == ABI_X64 else abi


# Makes dict cache-able "by reference" (assumed not to be mutated)
class BuildInfo(dict):

    def __hash__(self):
        return 0

    def __eq__(self, other):
        return self is other


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 name == 'cflags':
            fix_platform_default_defines(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('')
    blueprint_comment = values.get(BLUEPRINT_COMMENT_PROPERTY)
    if blueprint_comment:
        for comment_line in textwrap.wrap(blueprint_comment, width=70):
            output.append('// %s' % comment_line)
    output.append('%s {' % target_type)
    for (key, value) in values.items():
        if key != BLUEPRINT_COMMENT_PROPERTY:
            write_blueprint_key_value(output, key, value)
    output.append('}')


def gn_target_to_blueprint_target(target, target_info):
    if 'output_name' in target_info and target_info.get('type') != 'rust_library':
        return target_info['output_name']

    if target_info.get('type') == 'rust_library':
        return 'lib' + target_info['crate_name']

    if target_info.get('type') == 'shared_library':
        # Deduce name from the shared library path
        # end2end tests lib and libangle_util.so don't have output_name set for the early return above
        return os.path.splitext(os.path.basename(target_info['outputs'][0]))[0]

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

    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_generated_sources_to_blueprint_generated_sources(sources):
    # Blueprints only list source files in the sources list. Headers are only referenced though
    # include paths.
    generated_source_file_extension_allowlist = [
        '.c',
        '.cc',
        '.cpp',
    ]

    generated_source_targets = []
    for source in sources:
        if source in rust_ffi_gen_output_map and os.path.splitext(
                source)[1] in generated_source_file_extension_allowlist:
            generated_source_targets.append(rust_ffi_gen_output_map[source])
    return generated_source_targets


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 source in rust_ffi_gen_output_map:
            # these need to be placed under generated_sources and generated_headers entry in Android.bp
            continue
        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/zlib:zlib',
    '//third_party/zlib/google:compression_utils_portable',

    # end2end tests: -> platform libgtest, libgmock
    '//testing/gtest:gtest',
    '//testing/gmock:gmock',
    '//third_party/googletest:gtest',
    '//third_party/googletest:gmock',

    # Do not add chromium rust dependencies, we will use Android rust dependencies instead
    '//build/rust:cxx_cppdeps',
    '//build/rust:cxx_rustdeps',
    '//build/rust/allocator:allocator',
    '//build/rust/std:std',
    '//build/rust/gni_impl:rustc_print_cfg',
    '//third_party/rust/cxxbridge_cmd/v1:cxxbridge(//build/toolchain/linux:clang_x64_for_rust_host_build_tools)',

    # Do not add chromium perfetto dependencies, use Android perfetto library instead
    '//third_party/perfetto/src/tracing:client_api',
]

third_party_target_allowlist = [
    '//third_party/abseil-cpp',
    '//third_party/glslang/src',
    '//third_party/spirv-cross/src',
    '//third_party/spirv-headers/src',
    '//third_party/spirv-tools/src',
    '//third_party/vulkan-headers/src',
    '//third_party/vulkan-loader/src',
    '//third_party/vulkan-tools/src',
    '//third_party/vulkan-utility-libraries/src',
    '//third_party/vulkan-validation-layers/src',
    '//third_party/vulkan_memory_allocator',
]

include_blocklist = [
    '//buildtools/third_party/libc++/',
    '//third_party/libc++/src/',
    '//out/Android/gen/third_party/glslang/src/include/',
    '//third_party/zlib/',
    '//third_party/zlib/google/',
    # end2end tests: -> platform libgtest, libgmock
    '//third_party/googletest/custom/',
    '//third_party/googletest/src/googletest/include/',
    '//third_party/googletest/src/googlemock/include/',
    # rust ffi gen directory
    '//out/Android/gen/',
    '//out/Android/gen/src/',
    '//out/Android/gen/third_party/angle/src/',
    # Do not add chromium perfetto dependencies. The include will be resolved by Android libperfetto_client_experimental
    '//third_party/perfetto/include/',
    '//out/Android/gen/third_party/perfetto/',
    '//out/Android/gen/third_party/perfetto/build_config/',
    '//third_party/protobuf/*',
]

targets_using_jni = [
    '//src/tests:native_test_support_android',
    '//util:angle_util',
]


def get_rust_ffi_header_file_gen_target_name(rust_source_full_path):
    _, _, rust_source_without_full_path = rust_source_full_path.rpartition('/')
    generated_rust_ffi_header_file = "libcxx_" + rust_source_without_full_path.removesuffix(
        ".rs") + "_header"
    return generated_rust_ffi_header_file


def get_rust_ffi_source_file_gen_target_name(rust_source_full_path):
    _, _, rust_source_without_full_path = rust_source_full_path.rpartition('/')
    generated_rust_ffi_source_file = "libcxx_" + rust_source_without_full_path.removesuffix(
        ".rs") + "_cpp"
    return generated_rust_ffi_source_file


# Check if the given gn build target type and target information matches with the target that generates C++ headers
# and C++ source from rust files
def is_gn_target_rust_ffi(gn_dep_type, dep_info):
    if gn_dep_type in blueprint_gen_rust_ffi_types and 'script' in dep_info and dep_info[
            'script'] == '//third_party/rust/cxx/chromium_integration/run_cxxbridge.py':
        return True
    else:
        return False


@functools.lru_cache(maxsize=None)  # .cache() is py3.9 http://b/246559064#comment8
def gn_deps_to_blueprint_deps(abi, target, build_info):
    target_info = build_info[abi][target]
    static_libs = []
    shared_libs = []
    defaults = []
    generated_headers = []
    whole_static_libs = []
    header_libs = []
    if target in targets_using_jni:
        header_libs.append('jni_headers')
    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[abi][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':
                # ANGLE in Android repo does not depend on
                # angle_commit_id target to get ANGLE git has. See b/348044346.
                # Files include angle_commit.h will be able to find this
                # header file generated by roll_aosp.sh during ANGLE to
                # Android roll, instead of the version that is generated
                # by angle_commit_id build target at compile time.
                if blueprint_dep_name == 'angle_commit_id':
                    continue
                generated_headers.append(blueprint_dep_name)
            elif is_gn_target_rust_ffi(gn_dep_type, dep_info):
                for generated_file in dep_info['outputs']:
                    if generated_file in rust_ffi_gen_output_map and os.path.splitext(
                            generated_file)[1] == '.h':
                        generated_headers.append(rust_ffi_gen_output_map[generated_file])
            elif gn_dep_type == 'rust_library':
                whole_static_libs.append(blueprint_dep_name)

            # Blueprints do not chain linking of static libraries.
            (child_static_libs, _, _, _, child_generated_headers,
             _) = gn_deps_to_blueprint_deps(abi, dep, 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/zlib/google:compression_utils_portable':
            # Replace zlib by Android's zlib, compression_utils_portable is the root dependency
            shared_libs.append('libz')
            static_libs.extend(['zlib_google_compression_utils_portable'])
        elif dep == '//testing/gtest:gtest':
            static_libs.append('libgtest_ndk_c++')
        elif dep == '//testing/gmock:gmock':
            static_libs.append('libgmock_ndk')
        elif dep == '//third_party/perfetto/src/tracing:client_api':
            # Replace perfetto dependency with Android's prebuilt perfetto library
            static_libs.append('libperfetto_client_experimental')


    return static_libs, shared_libs, defaults, whole_static_libs, 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 and not lib.startswith('//'):
                android_lib = lib if '@' in lib else 'lib' + lib
                result.append(android_lib)
    return result


def is_include_dir_blocklisted(include_dir):
    norm_dir = include_dir.rstrip('/') + '/'
    for entry in include_blocklist:
        if entry.endswith('*'):
            prefix = entry[:-1].rstrip('/') + '/'
            if norm_dir.startswith(prefix):
                return True
        elif norm_dir == entry.rstrip('/') + '/':
            return True
    return False


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 not is_include_dir_blocklisted(include_dir):
                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'^-fvisibility.*$',  # forward visibility (https://gcc.gnu.org/wiki/Visibility) flags for better perf on x86
        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)

    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",
}

blueprint_rust_library_target_types = {
    "rust_library": "rust_ffi_static",
}


def merge_bps(bps_for_abis):
    common_bp = {}
    for abi in ABI_TARGETS:
        for key, values in bps_for_abis[abi].items():
            if not isinstance(values, list):
                # Assume everything that's not a list is common to all ABIs
                common_bp[key] = values
                continue

            # Find list values that are common to all ABIs
            values_in_all_abis = set.intersection(
                *[set(bps_for_abis[abi2].get(key, [])) for abi2 in ABI_TARGETS])

            for value in values:
                if value in values_in_all_abis or key == 'defaults':  # arch-specific defaults are not supported
                    common_bp.setdefault(key, [])
                    common_bp[key].append(value)
                else:
                    common_bp.setdefault('arch', {abi3: {} for abi3 in ABI_TARGETS})
                    abi_specific = common_bp['arch'][abi]
                    abi_specific.setdefault(key, [])
                    abi_specific[key].append(value)

    return common_bp


def rustlibrary_target_to_blueprint(target, build_info) -> list[tuple[str, dict]]:
    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_rust_library_target_types[target_info['type']]

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

        bp['crate_name'] = target_info['crate_name']

        bp['srcs'] = [gn_path_to_blueprint_path(target_info['crate_root'])]

        bp['rustlibs'] = {"libcxx"}

        bp['sdk_version'] = CURRENT_SDK_VERSION

        rustEditionPrefix = "--edition="
        if 'rustflags' in target_info:
            for rustflag in target_info['rustflags']:
                if rustflag.startswith(rustEditionPrefix):
                    bp['edition'] = rustflag[len(rustEditionPrefix):]
                    break

        bps_for_abis[abi] = bp
    common_bp = merge_bps(bps_for_abis)
    return [(blueprint_type, common_bp)]


def library_target_to_blueprint(target, build_info) -> list[tuple[str, dict]]:
    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['generated_sources'] = gn_generated_sources_to_blueprint_generated_sources(
                target_info['sources'])

        (bp['static_libs'], bp['shared_libs'], bp['defaults'], bp['whole_static_libs'],
         bp['generated_headers'],
         bp['header_libs']) = gn_deps_to_blueprint_deps(abi, target, build_info)
        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['defaults'].append('angle_common_library_cflags')

        bp['sdk_version'] = CURRENT_SDK_VERSION

        bp['stl'] = STL

        # Explicitly disable general Control Flow Integrity (CFI)
        bp['sanitize'] = {
            'cfi': False,
        }

        # Explicitly enable LTO and add aggressive LTO optimizations
        bp['whole_program_vtables'] = True
        bp['ldflags'] = ['-Wl,-plugin-opt,O2']

        if target in ROOT_TARGETS:
            bp['defaults'].append('angle_vendor_cc_defaults')
            bp['defaults'].append('angle_dma_buf_cc_defaults')
            bp['afdo'] = True
        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/glslang/src/include/glslang/build_info.h', 'glslang/build_info.h'),
        ('third_party/glslang/src', 'external/angle/third_party/glslang/src'),
        ('../../', ''),
        ('gen/', ''),
    ]

    # some args have special prefix added in front of the file name, we need to
    # take them out before transforming the file path, and then add them back:
    # e.g.
    # transform
    # --extinst=,../../third_party/spirv-headers/src/include/spirv/unified1/extinst.debuginfo.grammar.json
    # to
    # --extinst=,$(location third_party/spirv-headers/src/include/spirv/unified1/extinst.debuginfo.grammar.json)
    special_prefixs = [
        '--extinst=,',
        '--extinst=SHDEBUG100_,',
        '--extinst=CLDEBUG100_,',
    ]

    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)
        special_prefix = ''
        for special_item in special_prefixs:
            if remapped_path_arg.startswith(special_item):
                special_prefix = special_item
                break
        if special_prefix != '':
            remapped_path_arg = remapped_path_arg[len(special_prefix):]

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

    return result_args


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

blueprint_gen_rust_ffi_types = {
    "action_foreach": "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 separate_py_files_from_bp_srcs_entry(input_list):
    bp_tools_list = []  # Initialize the new list for ".py" items
    remaining_gn_input_list = []  # Initialize the list for the items that are not ".py"

    for item in input_list:
        if item.endswith(".py"):
            bp_tools_list.append(item)
        else:
            remaining_gn_input_list.append(item)

    return remaining_gn_input_list, bp_tools_list


# special handling the {{response_file_name}} args in GN:
# see https://gn.googlesource.com/gn/+/main/docs/reference.md#var_response_file_contents
# in GN, if we use response_file_contents, the GN build system will automatically
# write contents specified in response_file_contents arg into a temporary file
# identified by {{response_file_name}}. However, Android blueprint does not have
# the matching machanism. Android blueprint does automatically generate the
# temporary file and does not recognize '{{response_file_name}}'.
# To solve the problem:
# 1) replace the '{{response_file_name}}' in command argument with the new
# temporary file name.
# 2) write the content specified in 'response_file_contents' to the new temporary
# file
# This function completes step 1) above. It checks if there are
# '{{response_file_name}}' used in the command arguments. If there are,
# the function replaces the '{{response_file_name}}' with the new temp file
# named 'gn_response_file', and returns the new temp file to indicate
# we need to complete step 2)
def handle_gn_build_arg_response_file_name(command_arg_list):
    new_temp_file_name = None
    updated_args = command_arg_list[:]
    for index, arg in enumerate(updated_args):
        if arg == '{{response_file_name}}':
            new_temp_file_name = '$(genDir)/gn_response_file'
            updated_args[index] = new_temp_file_name
    return new_temp_file_name, updated_args


def add_rust_ffi_to_map(gn_rust_ffi_output_list, android_bp_rust_ffi_output,
                        android_bp_rust_ffi_gen_target):
    for gn_rust_ffi_output in gn_rust_ffi_output_list:
        if gn_rust_ffi_output.endswith(android_bp_rust_ffi_output):
            rust_ffi_gen_output_map[gn_rust_ffi_output] = android_bp_rust_ffi_gen_target
            return


def action_foreach_target_to_blueprint(abi, target, build_info) -> list[tuple[str, dict]]:
    target_info = build_info[abi][target]
    blueprint_type = blueprint_gen_rust_ffi_types[target_info['type']]
    output_rust_ffi_list = target_info['outputs']

    bp_list = []
    for rust_source in target_info['sources']:
        blueprint_source_path = gn_path_to_blueprint_path(rust_source)
        rust_ffi_header_bp = {'name': get_rust_ffi_header_file_gen_target_name(rust_source)}
        rust_ffi_header_bp['tools'] = ['cxxbridge']
        rust_ffi_header_bp['cmd'] = '$(location cxxbridge) $(in) --header > $(out)'
        rust_ffi_header_bp['srcs'] = [blueprint_source_path]
        rust_ffi_header_bp['out'] = [blueprint_source_path[len("src/"):] + ".h"]
        bp_list.append((blueprint_type, rust_ffi_header_bp))
        add_rust_ffi_to_map(output_rust_ffi_list, rust_ffi_header_bp['out'][0],
                            rust_ffi_header_bp['name'])

        rust_ffi_source_bp = {'name': get_rust_ffi_source_file_gen_target_name(rust_source)}
        rust_ffi_source_bp['tools'] = ['cxxbridge']
        rust_ffi_source_bp['cmd'] = '$(location cxxbridge) $(in) > $(out)'
        rust_ffi_source_bp['srcs'] = [blueprint_source_path]
        rust_ffi_source_bp['out'] = [blueprint_source_path[len("src/"):] + ".cc"]
        bp_list.append((blueprint_type, rust_ffi_source_bp))
        add_rust_ffi_to_map(output_rust_ffi_list, rust_ffi_source_bp['out'][0],
                            rust_ffi_source_bp['name'])
    return bp_list


def action_target_to_blueprint(abi, target, build_info) -> list[tuple[str, dict]]:
    target_info = build_info[abi][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)
        ]

    # Take "*.py" out from gn_inputs, they need to be listed in tool_files entry
    # in Android.bp.
    gn_inputs_without_python_script = gn_inputs
    extra_tool_files = []
    if 'script' in target_info:
        gn_inputs_without_python_script, extra_tool_files = separate_py_files_from_bp_srcs_entry(
            gn_inputs)

    bp_srcs = gn_paths_to_blueprint_paths(gn_inputs_without_python_script)

    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'])]
    if 'script' in target_info:
        # if there are more than 1 python script listed in "tool_files" entry in
        # Android.bp action target, we need to specify which script we are
        # invoking.
        if len(extra_tool_files) > 0:
            location = '$(location ' + target_info['script'].lstrip('/') + ')'
        else:
            location = '$(location)'
        bp['tool_files'] += gn_paths_to_blueprint_paths(extra_tool_files)
    else:
        location = '$(location)'

    new_temporary_gn_response_file, updated_args = handle_gn_build_arg_response_file_name(
        target_info['args'])

    if new_temporary_gn_response_file:
        # add the command 'echo $(in) > $(genDir)/gn_response_file' to
        # write $response_file_contents into the new_temporary_gn_response_file.
        cmd = ['echo $(in) >', new_temporary_gn_response_file, '&&', location
              ] + gn_action_args_to_blueprint_args(bp_srcs, bp_outputs, updated_args)
    else:
        cmd = [location] + gn_action_args_to_blueprint_args(bp_srcs, bp_outputs,
                                                            target_info['args'])

    bp['cmd'] = ' '.join(cmd)

    bp['sdk_version'] = CURRENT_SDK_VERSION

    return [(blueprint_type, bp)]


def gn_target_to_blueprint(target, build_info) -> list[tuple[str, dict]]:
    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(abi, target, build_info)
        elif gn_type in blueprint_rust_library_target_types:
            return rustlibrary_target_to_blueprint(target, build_info)
        elif is_gn_target_rust_ffi(gn_type, build_info[abi][target]):
            return action_foreach_target_to_blueprint(abi, target, build_info)
        else:
            # Target is not supported by this ABI
            continue


@functools.lru_cache(maxsize=None)
def get_gn_target_dependencies(abi, target, build_info):
    result = collections.OrderedDict()
    action_foreach_result = collections.OrderedDict()
    if build_info[abi][target]['type'] == 'action_foreach':
        action_foreach_result[target] = 1
    else:
        result[target] = 1

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

        # Recurse
        action_for_each_targets, other_targets = get_gn_target_dependencies(abi, dep, build_info)
        action_foreach_result.update(action_for_each_targets)
        result.update(other_targets)

    return action_foreach_result, result


def get_angle_in_vendor_flag_config():
    blueprint_results = []

    blueprint_results.append(('soong_config_module_type', {
        'name': 'angle_config_cc_defaults',
        'module_type': 'cc_defaults',
        'config_namespace': 'angle',
        'bool_variables': ['angle_in_vendor',],
        'properties': [
            'target.android.relative_install_path',
            'vendor',
        ],
    }))

    blueprint_results.append(('soong_config_bool_variable', {
        'name': 'angle_in_vendor',
    }))

    blueprint_results.append((
        'angle_config_cc_defaults',
        {
            'name': 'angle_vendor_cc_defaults',
            'vendor': False,
            'target': {
                'android': {
                    # Android EGL loader can not load from /system/egl/${LIB}
                    # path and hence don't set the relative path so that ANGLE
                    # libraries get built into /system/${LIB}
                    'relative_install_path': '',
                },
            },
            'soong_config_variables': {
                'angle_in_vendor': {
                    'vendor': True,
                    'target': {
                        'android': {
                            'relative_install_path': 'egl',
                        },
                    },
                },
            },
        }))

    return blueprint_results


def get_angle_android_dma_buf_flag_config(build_info):
    """
    Generates a list of Android.bp definitions for angle_android_dma_buf flag.
    """

    blueprint_results = []

    blueprint_results.append(('soong_config_module_type', {
        'name': 'angle_dma_buf_config_cc_defaults',
        'module_type': 'cc_defaults',
        'config_namespace': 'angle',
        'bool_variables': ['angle_android_dma_buf'],
        'properties': ['defaults']
    }))

    blueprint_results.append(('soong_config_bool_variable', {
        'name': 'angle_android_dma_buf',
    }))

    blueprint_results.append(('angle_dma_buf_config_cc_defaults', {
        BLUEPRINT_COMMENT_PROPERTY:
            ('Note: this is a no-op for most builds, only applies to products that explicitly '
             'enable the angle_android_dma_buf config flag. See b/353262025 for details of the '
             'products that use it.'),
        'name': 'angle_dma_buf_cc_defaults',
        'soong_config_variables': {
            'angle_android_dma_buf': {
                'defaults': [gn_target_to_blueprint_target(DMA_BUF_TARGET, {})],
            }
        },
    }))

    return blueprint_results


# returns list of (blueprint module type, dict with contents)
def get_blueprint_targets_from_build_info(build_info: BuildInfo) -> List[Tuple[str, dict]]:
    non_action_foreach_targets_to_write = collections.OrderedDict()
    action_foreach_targets_to_write = collections.OrderedDict()
    for abi in ABI_TARGETS:
        for root_target in ROOT_TARGETS + [END2END_TEST_TARGET, DMA_BUF_TARGET]:
            action_foreach_targets, non_action_foreach_targets = get_gn_target_dependencies(
                abi, root_target, build_info)
            action_foreach_targets_to_write.update(action_foreach_targets)
            non_action_foreach_targets_to_write.update(non_action_foreach_targets)

    generated_targets = []

    # Process target whose type is action_foreach
    # We need to insert generated header and source to rust_ffi_gen_output_map hash map first
    # before processing other targets
    for action_foreach_target in action_foreach_targets_to_write.keys():
        generated_target_list = gn_target_to_blueprint(action_foreach_target, build_info)
        generated_targets.extend(generated_target_list)

    for target in reversed(non_action_foreach_targets_to_write.keys()):
        # Do not export angle_commit_id target in Android.bp, because the script
        # src/commit_id.py invoked by this target  can't guarantee to generate a
        # meaningful ANGLE git hash during compile time, see b/348044346.
        # The script src/commit_id.py will be invoked by roll_aosp.h during
        # ANGLE to Android roll time, and the ANGLE git hash will be output in
        # {AndroidANGLERoot}/angle_commmit.h.
        if target == '//:angle_commit_id':
            continue
        generated_target_list = gn_target_to_blueprint(target, build_info)
        generated_targets.extend(generated_target_list)

    return generated_targets


def handle_angle_non_conformant_extensions_and_versions(
    generated_targets: List[Tuple[str, dict]],
    blueprint_targets: List[dict],
):
    """Replace the non conformant cflags with a separate cc_defaults.

    The downstream can custom the cflags easier.
    """
    non_conform_cflag = '-DANGLE_EXPOSE_NON_CONFORMANT_EXTENSIONS_AND_VERSIONS'
    non_conform_defaults = 'angle_non_conformant_extensions_and_versions_cflags'

    blueprint_targets.append(('cc_defaults', {
        'name': non_conform_defaults,
        'cflags': [non_conform_cflag],
    }))

    for _, bp in generated_targets:
        if 'cflags' in bp and non_conform_cflag in bp['cflags']:
            bp['cflags'] = list(set(bp['cflags']) - {non_conform_cflag})
            bp['defaults'].append(non_conform_defaults)


def fix_platform_default_defines(cflags: list[str]) -> None:
    """Avoids macro redefinition errors for flags specified by Android.

    Android may specify platform defaults for macros like `_FORTIFY_SOURCE` and
    `_LIBCPP_HARDENING_MODE`. If both Android and Angle provide different values
    for these (e.g., `-D_FORTIFY_SOURCE=3 -D_FORTIFY_SOURCE=2`), Clang will emit
    errors about macro redefinitions.

    This inserts `-U${FLAG}` before Angle's definitions, to avoid those errors.
    """
    flags_to_check = (
        '_FORTIFY_SOURCE',
        '_LIBCPP_HARDENING_MODE',
    )
    for flag in flags_to_check:
        d_flag = f'-D{flag}'

        # It's _technically_ possible that we have multiple instances of these
        # flags in a single command. If these flags _differ_ in value, they
        # should already be a build error, so we only need to worry about adding
        # the `-U` flag before the first.
        flag_index = next((i for i, cflag in enumerate(cflags) if d_flag in cflag), None)
        if flag_index is not None:
            cflags.insert(flag_index, f'-U{flag}')


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

    for abi in ABI_TARGETS:
        parser.add_argument(
            '--gn_json_' + gn_abi(abi),
            help=gn_abi(abi) +
            ' gn desc file in json format. Generated with \'gn desc <out_dir> --format=json "*"\'.',
            required=True)
    parser.add_argument('--output', help='output file (e.g. Android.bp)')
    args = vars(parser.parse_args())

    infos = {}
    for abi in ABI_TARGETS:
        with open(args['gn_json_' + gn_abi(abi)], 'r') as f:
            infos[abi] = json.load(f)

    build_info = BuildInfo(infos)

    blueprint_targets = []

    blueprint_targets.extend(get_angle_in_vendor_flag_config())
    blueprint_targets.extend(get_angle_android_dma_buf_flag_config(build_info))

    blueprint_targets.append((
        'cc_defaults',
        {
            'name':
                'angle_common_library_cflags',
            'cflags': [
                # Chrome and Android use different versions of Clang which support differnt warning options.
                # Ignore errors about unrecognized warning flags.
                '-Wno-unknown-warning-option',
                '-O2',
                # Override AOSP build flags to match ANGLE's CQ testing and reduce binary size
                '-fno-unwind-tables',
                # Disable stack protector to reduce cpu overhead.
                '-fno-stack-protector',
            ],
        }))

    generated_targets = get_blueprint_targets_from_build_info(build_info)

    # Will modify generated_targets and blueprint_targets in-place to handle the
    # angle_expose_non_conformant_extensions_and_versions gn argument.
    handle_angle_non_conformant_extensions_and_versions(generated_targets, blueprint_targets)

    # Move cflags that are repeated in each target to cc_defaults
    # 1. Identify common cflags across all generated targets.
    targets_with_cflags = [bp for _, bp in generated_targets if 'cflags' in bp]
    if targets_with_cflags:
        common_cflags = set.intersection(*(set(bp['cflags']) for bp in targets_with_cflags))
    else:
        common_cflags = set()

    # 2. Identify common arch-specific cflags.
    common_arch_cflags = {}
    for abi in ABI_TARGETS:
        targets_with_arch_cflags = [
            bp for _, bp in generated_targets
            if 'arch' in bp and abi in bp['arch'] and 'cflags' in bp['arch'][abi]
        ]
        if targets_with_arch_cflags:
            common_arch_cflags[abi] = set.intersection(
                *(set(bp['arch'][abi]['cflags']) for bp in targets_with_arch_cflags))
        else:
            common_arch_cflags[abi] = set()

    # 3. Move these common flags to angle_common_auto_cflags and remove from individual targets.
    for _, bp in generated_targets:
        if 'cflags' in bp:
            bp['cflags'] = list(set(bp['cflags']) - common_cflags)
            # Every generated target that had cflags should inherit from angle_common_auto_cflags
            if 'angle_common_auto_cflags' not in bp.get('defaults', []):
                bp.setdefault('defaults', []).append('angle_common_auto_cflags')

        for abi, flags in common_arch_cflags.items():
            if flags and 'arch' in bp and abi in bp['arch'] and 'cflags' in bp['arch'][abi]:
                bp['arch'][abi]['cflags'] = list(set(bp['arch'][abi]['cflags']) - flags)
                # Cleanup empty structures
                if not bp['arch'][abi]['cflags']:
                    del bp['arch'][abi]['cflags']
                if not bp['arch'][abi]:
                    del bp['arch'][abi]
                if not bp['arch']:
                    del bp['arch']

    # 4. Create the consolidated cc_defaults
    auto_cflags_bp = {
        'name': 'angle_common_auto_cflags',
        'cflags': list(common_cflags),
    }
    if any(common_arch_cflags.values()):
        auto_cflags_bp['arch'] = {}
        for abi, flags in common_arch_cflags.items():
            if flags:
                auto_cflags_bp['arch'][abi] = {'cflags': list(flags)}

    blueprint_targets.append(('cc_defaults', auto_cflags_bp))
    blueprint_targets.extend(generated_targets)

    # 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/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/glslang/LICENSE',
            'third_party/glslang/src/LICENSE.txt',
            'third_party/re2/LICENSE',
            'third_party/spirv-headers/LICENSE',
            'third_party/spirv-headers/src/LICENSE',
            'third_party/spirv-tools/LICENSE',
            'third_party/spirv-tools/src/LICENSE',
            'third_party/spirv-tools/src/utils/vscode/src/lsp/LICENSE',
            'third_party/vulkan-headers/LICENSE.txt',
            'third_party/vulkan-headers/src/LICENSE.md',
            'third_party/vulkan_memory_allocator/LICENSE.txt',
            '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 and permissions xml
    blueprint_targets.append((
        'filegroup',
        {
            'name':
                'ANGLE_srcs',
            # We only need 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.
            # However, the internal branch currently uses these files with patches in that branch.
            'srcs': [
                'src/android_system_settings/src/com/android/angle/MainActivity.java',
                'src/android_system_settings/src/com/android/angle/common/AngleRuleHelper.java',
                'src/android_system_settings/src/com/android/angle/common/GlobalSettings.java',
                'src/android_system_settings/src/com/android/angle/common/MainFragment.java',
                'src/android_system_settings/src/com/android/angle/common/Receiver.java',
                'src/android_system_settings/src/com/android/angle/common/SearchProvider.java',
            ],
        }))

    blueprint_targets.append(('prebuilt_etc', {
        'name': 'android.software.angle.xml',
        'src': 'android/android.software.angle.xml',
        'product_specific': True,
        'sub_dir': 'permissions',
    }))

    blueprint_targets.append((
        'java_defaults',
        {
            'name': 'ANGLE_java_defaults',
            'sdk_version': 'system_current',
            'target_sdk_version': TARGET_SDK_VERSION,
            'min_sdk_version': MIN_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': [
                '-0 .json',  # Don't compress *.json files
                "--extra-packages com.android.angle.common",
            ],
            'srcs': [':ANGLE_srcs'],
            'privileged': True,
            'product_specific': True,
            'owner': 'google',
            'required': ['android.software.angle.xml'],
        }))

    blueprint_targets.append(('android_library', {
        'name': 'ANGLE_library',
        'sdk_version': 'system_current',
        'target_sdk_version': TARGET_SDK_VERSION,
        'min_sdk_version': MIN_SDK_VERSION,
        'resource_dirs': ['src/android_system_settings/res',],
        'asset_dirs': ['src/android_system_settings/assets',],
        'aaptflags': ['-0 .json',],
        'manifest': 'src/android_system_settings/src/com/android/angle/AndroidManifest.xml',
        'static_libs': ['androidx.preference_preference',],
    }))

    blueprint_targets.append(('android_app', {
        'name': 'ANGLE',
        'defaults': ['ANGLE_java_defaults'],
        'manifest': 'src/android_system_settings/src/com/android/angle/AndroidManifest.xml',
        'static_libs': ['ANGLE_library'],
        'optimize': {
            'enabled': True,
            'shrink': True,
        },
        'asset_dirs': ['src/android_system_settings/assets',],
    }))

    blueprint_targets.append((
        'java_defaults',
        {
            'name': 'ANGLE_java_settings_defaults',
            'sdk_version': 'system_current',
            'target_sdk_version': TARGET_SDK_VERSION,
            'min_sdk_version': MIN_SDK_VERSION,
            'compile_multilib': 'both',
            'use_embedded_native_libs': True,
            'aaptflags': [
                '-0 .json',  # Don't compress *.json files
                "--extra-packages com.android.angle.common",
            ],
            'srcs': [':ANGLE_srcs'],
            'privileged': True,
            'product_specific': True,
            'owner': 'google',
            'required': ['android.software.angle.xml'],
        }))

    blueprint_targets.append(('android_app', {
        'name': 'ANGLE_settings',
        'defaults': ['ANGLE_java_settings_defaults'],
        'manifest': 'src/android_system_settings/src/com/android/angle/AndroidManifest.xml',
        'static_libs': ['ANGLE_library'],
        'optimize': {
            'enabled': True,
            'shrink': True,
        },
        '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)

    with open(args['output'], 'w') as f:
        f.write('\n'.join(output) + '\n')


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