#!/usr/bin/env python3
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This tool translates a collection of BUILD.gn files into a mostly equivalent
# Android.bp file for the Android Soong build system. The input to the tool is a
# JSON description of the GN build definition generated with the following
# command:
#
#   gn desc out --format=json --all-toolchains "//*" > desc.json
#
# The tool is then given a list of GN labels for which to generate Android.bp
# build rules. The dependencies for the GN labels are squashed to the generated
# Android.bp target, except for actions which get their own genrule. Some
# libraries are also mapped to their Android equivalents -- see |builtin_deps|.

import argparse
import collections
import json
import os
import re
import sys

import gn_utils

from compat import itervalues

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Arguments for the GN output directory.
gn_args = ' '.join([
    'is_debug=false',
    'is_perfetto_build_generator=true',
    'perfetto_build_with_android=true',
    'target_cpu="arm"',
    'target_os="android"',
])

# Default targets to translate to the blueprint file.
default_targets = [
    '//:libperfetto_client_experimental',
    '//:libperfetto',
    '//:perfetto_integrationtests',
    '//:perfetto_unittests',
    '//protos/perfetto/trace:perfetto_trace_protos',
    '//src/android_internal:libperfetto_android_internal',
    '//src/perfetto_cmd:perfetto',
    '//src/perfetto_cmd:trigger_perfetto',
    '//src/profiling/memory:heapprofd_client',
    '//src/profiling/memory:heapprofd_client_api',
    '//src/profiling/memory:heapprofd_api_noop',
    '//src/profiling/memory:heapprofd',
    '//src/profiling/memory:heapprofd_standalone_client',
    '//src/profiling/perf:traced_perf',
    '//src/traced/probes:traced_probes',
    '//src/traced/service:traced',
    '//src/trace_processor:trace_processor_shell',
    '//test/cts:perfetto_cts_deps',
    '//test/cts:perfetto_cts_jni_deps',
    '//test:perfetto_gtest_logcat_printer',
    '//test/vts:perfetto_vts_deps',
]

# Host targets
ipc_plugin = '//src/ipc/protoc_plugin:ipc_plugin(%s)' % gn_utils.HOST_TOOLCHAIN
protozero_plugin = '//src/protozero/protoc_plugin:protozero_plugin(%s)' % (
    gn_utils.HOST_TOOLCHAIN)
cppgen_plugin = '//src/protozero/protoc_plugin:cppgen_plugin(%s)' % (
    gn_utils.HOST_TOOLCHAIN)

default_targets += [
    '//src/traceconv:traceconv(%s)' % gn_utils.HOST_TOOLCHAIN,
    protozero_plugin,
    ipc_plugin,
]

# Defines a custom init_rc argument to be applied to the corresponding output
# blueprint target.
target_initrc = {
    '//src/traced/service:traced': {'perfetto.rc'},
    '//src/profiling/memory:heapprofd': {'heapprofd.rc'},
    '//src/profiling/perf:traced_perf': {'traced_perf.rc'},
}

target_host_supported = [
    '//:libperfetto',
    '//:libperfetto_client_experimental',
    '//protos/perfetto/trace:perfetto_trace_protos',
    '//src/trace_processor:demangle',
    '//src/trace_processor:trace_processor_shell',
]

target_vendor_available = [
    '//:libperfetto_client_experimental',
]

# Proto target groups which will be made public.
proto_groups = {
    'trace': [
        '//protos/perfetto/trace:non_minimal_source_set',
        '//protos/perfetto/trace:minimal_source_set'
    ],
}

# All module names are prefixed with this string to avoid collisions.
module_prefix = 'perfetto_'

# Shared libraries which are directly translated to Android system equivalents.
shared_library_allowlist = [
    'android',
    'android.hardware.atrace@1.0',
    'android.hardware.health@2.0',
    'android.hardware.health-V1-ndk',
    'android.hardware.power.stats@1.0',
    "android.hardware.power.stats-V1-cpp",
    'base',
    'binder',
    'binder_ndk',
    'cutils',
    'hidlbase',
    'hidltransport',
    'hwbinder',
    'incident',
    'log',
    'services',
    'statssocket',
    "tracingproxy",
    'utils',
]

# Static libraries which are directly translated to Android system equivalents.
static_library_allowlist = [
    'statslog_perfetto',
]

# Name of the module which settings such as compiler flags for all other
# modules.
defaults_module = module_prefix + 'defaults'

# Location of the project in the Android source tree.
tree_path = 'external/perfetto'

# Path for the protobuf sources in the standalone build.
buildtools_protobuf_src = '//buildtools/protobuf/src'

# Location of the protobuf src dir in the Android source tree.
android_protobuf_src = 'external/protobuf/src'

# Compiler flags which are passed through to the blueprint.
cflag_allowlist = r'^-DPERFETTO.*$'

# Compiler defines which are passed through to the blueprint.
define_allowlist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)|(HAVE_HIDDEN)$'

# The directory where the generated perfetto_build_flags.h will be copied into.
buildflags_dir = 'include/perfetto/base/build_configs/android_tree'


def enumerate_data_deps():
  with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
    lines = f.readlines()
  for line in (line.strip() for line in lines if not line.startswith('#')):
    assert os.path.exists(line), 'file %s should exist' % line
    if line.startswith('test/data/'):
      # Skip test data files that require GCS. They are only for benchmarks.
      # We don't run benchmarks in the android tree.
      continue
    if line.endswith('/.'):
      yield line[:-1] + '**/*'
    else:
      yield line


# Additional arguments to apply to Android.bp rules.
additional_args = {
    'heapprofd_client_api': [
        ('static_libs', {'libasync_safe'}),
        # heapprofd_client_api MUST NOT have global constructors. Because it
        # is loaded in an __attribute__((constructor)) of libc, we cannot
        # guarantee that the global constructors get run before it is used.
        ('cflags', {'-Wglobal-constructors', '-Werror=global-constructors'}),
        ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
        ('stubs', {
            'versions': ['S'],
            'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
        }),
        ('export_include_dirs', {'src/profiling/memory/include'}),
    ],
    'heapprofd_api_noop': [
        ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
        ('stubs', {
            'versions': ['S'],
            'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
        }),
        ('export_include_dirs', {'src/profiling/memory/include'}),
    ],
    'heapprofd_client': [
        ('include_dirs', {'bionic/libc'}),
        ('static_libs', {'libasync_safe'}),
    ],
    'heapprofd_standalone_client': [
        ('static_libs', {'libasync_safe'}),
        ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
        ('export_include_dirs', {'src/profiling/memory/include'}),
        ('stl', 'libc++_static'),
    ],
    'perfetto_unittests': [
        ('data', set(enumerate_data_deps())),
        ('include_dirs', {'bionic/libc/kernel'}),
    ],
    'perfetto_integrationtests': [
        ('test_suites', {'general-tests'}),
        ('test_config', 'PerfettoIntegrationTests.xml'),
    ],
    'traced_probes': [('required', {
        'libperfetto_android_internal', 'trigger_perfetto', 'traced_perf',
        'mm_events'
    }),],
    'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
    'trace_processor_shell': [
        ('strip', {
            'all': True
        }),
        ('host', {
            'stl': 'libc++_static',
            'dist': {
                'targets': ['sdk_repo']
            },
        }),
    ],
    'libperfetto_client_experimental': [
        ('apex_available', {
            '//apex_available:platform', 'com.android.art',
            'com.android.art.debug'
        }),
        ('min_sdk_version', 'S'),
        ('shared_libs', {'liblog'}),
        ('export_include_dirs', {'include', buildflags_dir}),
    ],
    'perfetto_trace_protos': [
        ('apex_available', {
            '//apex_available:platform', 'com.android.art',
            'com.android.art.debug'
        }),
        ('min_sdk_version', 'S'),
    ],
    'libperfetto': [('export_include_dirs', {'include', buildflags_dir}),],
}


def enable_gtest_and_gmock(module):
  module.static_libs.add('libgmock')
  module.static_libs.add('libgtest')
  if module.name != 'perfetto_gtest_logcat_printer':
    module.whole_static_libs.add('perfetto_gtest_logcat_printer')


def enable_protobuf_full(module):
  if module.type == 'cc_binary_host':
    module.static_libs.add('libprotobuf-cpp-full')
  elif module.host_supported:
    module.host.static_libs.add('libprotobuf-cpp-full')
    module.android.shared_libs.add('libprotobuf-cpp-full')
  else:
    module.shared_libs.add('libprotobuf-cpp-full')


def enable_protobuf_lite(module):
  module.shared_libs.add('libprotobuf-cpp-lite')


def enable_protoc_lib(module):
  if module.type == 'cc_binary_host':
    module.static_libs.add('libprotoc')
  else:
    module.shared_libs.add('libprotoc')


def enable_libunwindstack(module):
  if module.name != 'heapprofd_standalone_client':
    module.shared_libs.add('libunwindstack')
    module.shared_libs.add('libprocinfo')
    module.shared_libs.add('libbase')
  else:
    module.static_libs.add('libunwindstack')
    module.static_libs.add('libprocinfo')
    module.static_libs.add('libbase')
    module.static_libs.add('liblzma')
    module.static_libs.add('libdexfile_support')
    module.runtime_libs.add('libdexfile')  # libdexfile_support dependency


def enable_libunwind(module):
  # libunwind is disabled on Darwin so we cannot depend on it.
  pass


def enable_sqlite(module):
  if module.type == 'cc_binary_host':
    module.static_libs.add('libsqlite')
    module.static_libs.add('sqlite_ext_percentile')
  elif module.host_supported:
    # Copy what the sqlite3 command line tool does.
    module.android.shared_libs.add('libsqlite')
    module.android.shared_libs.add('libicu')
    module.android.shared_libs.add('liblog')
    module.android.shared_libs.add('libutils')
    module.android.static_libs.add('sqlite_ext_percentile')
    module.host.static_libs.add('libsqlite')
    module.host.static_libs.add('sqlite_ext_percentile')
  else:
    module.shared_libs.add('libsqlite')
    module.shared_libs.add('libicu')
    module.shared_libs.add('liblog')
    module.shared_libs.add('libutils')
    module.static_libs.add('sqlite_ext_percentile')


def enable_zlib(module):
  if module.type == 'cc_binary_host':
    module.static_libs.add('libz')
  elif module.host_supported:
    module.android.shared_libs.add('libz')
    module.host.static_libs.add('libz')
  else:
    module.shared_libs.add('libz')


def enable_uapi_headers(module):
  module.include_dirs.add('bionic/libc/kernel')


def enable_bionic_libc_platform_headers_on_android(module):
  module.header_libs.add('bionic_libc_platform_headers')


# Android equivalents for third-party libraries that the upstream project
# depends on.
builtin_deps = {
    '//gn:default_deps':
        lambda x: None,
    '//gn:gtest_main':
        lambda x: None,
    '//gn:protoc':
        lambda x: None,
    '//gn:gtest_and_gmock':
        enable_gtest_and_gmock,
    '//gn:libunwind':
        enable_libunwind,
    '//gn:protobuf_full':
        enable_protobuf_full,
    '//gn:protobuf_lite':
        enable_protobuf_lite,
    '//gn:protoc_lib':
        enable_protoc_lib,
    '//gn:libunwindstack':
        enable_libunwindstack,
    '//gn:sqlite':
        enable_sqlite,
    '//gn:zlib':
        enable_zlib,
    '//gn:bionic_kernel_uapi_headers':
        enable_uapi_headers,
    '//src/profiling/memory:bionic_libc_platform_headers_on_android':
        enable_bionic_libc_platform_headers_on_android,
}

# ----------------------------------------------------------------------------
# End of configuration.
# ----------------------------------------------------------------------------


class Error(Exception):
  pass


class ThrowingArgumentParser(argparse.ArgumentParser):

  def __init__(self, context):
    super(ThrowingArgumentParser, self).__init__()
    self.context = context

  def error(self, message):
    raise Error('%s: %s' % (self.context, message))


def write_blueprint_key_value(output, name, value, sort=True):
  """Writes a Blueprint key-value pair to the output"""

  if isinstance(value, bool):
    if value:
      output.append('    %s: true,' % name)
    else:
      output.append('    %s: false,' % name)
    return
  if not value:
    return
  if isinstance(value, set):
    value = sorted(value)
  if isinstance(value, list):
    output.append('    %s: [' % name)
    for item in sorted(value) if sort else value:
      output.append('        "%s",' % item)
    output.append('    ],')
    return
  if isinstance(value, Target):
    value.to_string(output)
    return
  if isinstance(value, dict):
    kv_output = []
    for k, v in value.items():
      write_blueprint_key_value(kv_output, k, v)

    output.append('    %s: {' % name)
    for line in kv_output:
      output.append('    %s' % line)
    output.append('    },')
    return
  output.append('    %s: "%s",' % (name, value))


class Target(object):
  """A target-scoped part of a module"""

  def __init__(self, name):
    self.name = name
    self.shared_libs = set()
    self.static_libs = set()
    self.whole_static_libs = set()
    self.cflags = set()
    self.dist = dict()
    self.strip = dict()
    self.stl = None

  def to_string(self, output):
    nested_out = []
    self._output_field(nested_out, 'shared_libs')
    self._output_field(nested_out, 'static_libs')
    self._output_field(nested_out, 'whole_static_libs')
    self._output_field(nested_out, 'cflags')
    self._output_field(nested_out, 'stl')
    self._output_field(nested_out, 'dist')
    self._output_field(nested_out, 'strip')

    if nested_out:
      output.append('    %s: {' % self.name)
      for line in nested_out:
        output.append('    %s' % line)
      output.append('    },')

  def _output_field(self, output, name, sort=True):
    value = getattr(self, name)
    return write_blueprint_key_value(output, name, value, sort)


class Module(object):
  """A single module (e.g., cc_binary, cc_test) in a blueprint."""

  def __init__(self, mod_type, name, gn_target):
    self.type = mod_type
    self.gn_target = gn_target
    self.name = name
    self.srcs = set()
    self.comment = 'GN: ' + gn_utils.label_without_toolchain(gn_target)
    self.shared_libs = set()
    self.static_libs = set()
    self.whole_static_libs = set()
    self.runtime_libs = set()
    self.tools = set()
    self.cmd = None
    self.host_supported = False
    self.vendor_available = False
    self.init_rc = set()
    self.out = set()
    self.export_include_dirs = set()
    self.generated_headers = set()
    self.export_generated_headers = set()
    self.defaults = set()
    self.cflags = set()
    self.include_dirs = set()
    self.header_libs = set()
    self.required = set()
    self.user_debug_flag = False
    self.tool_files = None
    self.android = Target('android')
    self.host = Target('host')
    self.lto = None
    self.stl = None
    self.dist = dict()
    self.strip = dict()
    self.data = set()
    self.apex_available = set()
    self.min_sdk_version = None
    self.proto = dict()
    # The genrule_XXX below are properties that must to be propagated back
    # on the module(s) that depend on the genrule.
    self.genrule_headers = set()
    self.genrule_srcs = set()
    self.genrule_shared_libs = set()
    self.version_script = None
    self.test_suites = set()
    self.test_config = None
    self.stubs = {}

  def to_string(self, output):
    if self.comment:
      output.append('// %s' % self.comment)
    output.append('%s {' % self.type)
    self._output_field(output, 'name')
    self._output_field(output, 'srcs')
    self._output_field(output, 'shared_libs')
    self._output_field(output, 'static_libs')
    self._output_field(output, 'whole_static_libs')
    self._output_field(output, 'runtime_libs')
    self._output_field(output, 'tools')
    self._output_field(output, 'cmd', sort=False)
    if self.host_supported:
      self._output_field(output, 'host_supported')
    if self.vendor_available:
      self._output_field(output, 'vendor_available')
    self._output_field(output, 'init_rc')
    self._output_field(output, 'out')
    self._output_field(output, 'export_include_dirs')
    self._output_field(output, 'generated_headers')
    self._output_field(output, 'export_generated_headers')
    self._output_field(output, 'defaults')
    self._output_field(output, 'cflags')
    self._output_field(output, 'include_dirs')
    self._output_field(output, 'header_libs')
    self._output_field(output, 'required')
    self._output_field(output, 'dist')
    self._output_field(output, 'strip')
    self._output_field(output, 'tool_files')
    self._output_field(output, 'data')
    self._output_field(output, 'stl')
    self._output_field(output, 'apex_available')
    self._output_field(output, 'min_sdk_version')
    self._output_field(output, 'version_script')
    self._output_field(output, 'test_suites')
    self._output_field(output, 'test_config')
    self._output_field(output, 'stubs')
    self._output_field(output, 'proto')

    target_out = []
    self._output_field(target_out, 'android')
    self._output_field(target_out, 'host')
    if target_out:
      output.append('    target: {')
      for line in target_out:
        output.append('    %s' % line)
      output.append('    },')

    if self.user_debug_flag:
      output.append('    product_variables: {')
      output.append('        debuggable: {')
      output.append(
          '            cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
      output.append('        },')
      output.append('    },')
    if self.lto is not None:
      output.append('    target: {')
      output.append('        android: {')
      output.append('            lto: {')
      output.append('                thin: %s,' %
                    'true' if self.lto else 'false')
      output.append('            },')
      output.append('        },')
      output.append('    },')
    output.append('}')
    output.append('')

  def add_android_static_lib(self, lib):
    if self.type == 'cc_binary_host':
      raise Exception('Adding Android static lib for host tool is unsupported')
    elif self.host_supported:
      self.android.static_libs.add(lib)
    else:
      self.static_libs.add(lib)

  def add_android_shared_lib(self, lib):
    if self.type == 'cc_binary_host':
      raise Exception('Adding Android shared lib for host tool is unsupported')
    elif self.host_supported:
      self.android.shared_libs.add(lib)
    else:
      self.shared_libs.add(lib)

  def _output_field(self, output, name, sort=True):
    value = getattr(self, name)
    return write_blueprint_key_value(output, name, value, sort)


class Blueprint(object):
  """In-memory representation of an Android.bp file."""

  def __init__(self):
    self.modules = {}

  def add_module(self, module):
    """Adds a new module to the blueprint, replacing any existing module
        with the same name.

        Args:
            module: Module instance.
        """
    self.modules[module.name] = module

  def to_string(self, output):
    for m in sorted(itervalues(self.modules), key=lambda m: m.name):
      m.to_string(output)


def label_to_module_name(label):
  """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
  # If the label is explicibly listed in the default target list, don't prefix
  # its name and return just the target name. This is so tools like
  # "traceconv" stay as such in the Android tree.
  label_without_toolchain = gn_utils.label_without_toolchain(label)
  if label in default_targets or label_without_toolchain in default_targets:
    return label_without_toolchain.split(':')[-1]

  module = re.sub(r'^//:?', '', label_without_toolchain)
  module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
  if not module.startswith(module_prefix):
    return module_prefix + module
  return module


def is_supported_source_file(name):
  """Returns True if |name| can appear in a 'srcs' list."""
  return os.path.splitext(name)[1] in ['.c', '.cc', '.proto']


def create_proto_modules(blueprint, gn, target):
  """Generate genrules for a proto GN target.

    GN actions are used to dynamically generate files during the build. The
    Soong equivalent is a genrule. This function turns a specific kind of
    genrule which turns .proto files into source and header files into a pair
    equivalent genrules.

    Args:
        blueprint: Blueprint instance which is being generated.
        target: gn_utils.Target object.

    Returns:
        The source_genrule module.
    """
  assert (target.type == 'proto_library')

  tools = {'aprotoc'}
  cpp_out_dir = '$(genDir)/%s/' % tree_path
  target_module_name = label_to_module_name(target.name)

  # In GN builds the proto path is always relative to the output directory
  # (out/tmp.xxx).
  cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
  cmd += ['--proto_path=%s' % tree_path]

  if buildtools_protobuf_src in target.proto_paths:
    cmd += ['--proto_path=%s' % android_protobuf_src]

  # We don't generate any targets for source_set proto modules because
  # they will be inlined into other modules if required.
  if target.proto_plugin == 'source_set':
    return None

  # Descriptor targets only generate a single target.
  if target.proto_plugin == 'descriptor':
    out = '{}.bin'.format(target_module_name)

    cmd += ['--descriptor_set_out=$(out)']
    cmd += ['$(in)']

    descriptor_module = Module('genrule', target_module_name, target.name)
    descriptor_module.cmd = ' '.join(cmd)
    descriptor_module.out = [out]
    descriptor_module.tools = tools
    blueprint.add_module(descriptor_module)

    # Recursively extract the .proto files of all the dependencies and
    # add them to srcs.
    descriptor_module.srcs.update(
        gn_utils.label_to_path(src) for src in target.sources)
    for dep in target.transitive_proto_deps:
      current_target = gn.get_target(dep)
      descriptor_module.srcs.update(
          gn_utils.label_to_path(src) for src in current_target.sources)

    return descriptor_module

  # We create two genrules for each proto target: one for the headers and
  # another for the sources. This is because the module that depends on the
  # generated files needs to declare two different types of dependencies --
  # source files in 'srcs' and headers in 'generated_headers' -- and it's not
  # valid to generate .h files from a source dependency and vice versa.
  source_module_name = target_module_name + '_gen'
  source_module = Module('genrule', source_module_name, target.name)
  blueprint.add_module(source_module)
  source_module.srcs.update(
      gn_utils.label_to_path(src) for src in target.sources)

  header_module = Module('genrule', source_module_name + '_headers',
                         target.name)
  blueprint.add_module(header_module)
  header_module.srcs = set(source_module.srcs)

  # TODO(primiano): at some point we should remove this. This was introduced
  # by aosp/1108421 when adding "protos/" to .proto include paths, in order to
  # avoid doing multi-repo changes and allow old clients in the android tree
  # to still do the old #include "perfetto/..." rather than
  # #include "protos/perfetto/...".
  header_module.export_include_dirs = {'.', 'protos'}

  source_module.genrule_srcs.add(':' + source_module.name)
  source_module.genrule_headers.add(header_module.name)

  if target.proto_plugin == 'proto':
    suffixes = ['pb']
    source_module.genrule_shared_libs.add('libprotobuf-cpp-lite')
    cmd += ['--cpp_out=lite=true:' + cpp_out_dir]
  elif target.proto_plugin == 'protozero':
    suffixes = ['pbzero']
    plugin = create_modules_from_target(blueprint, gn, protozero_plugin)
    tools.add(plugin.name)
    cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
    cmd += ['--plugin_out=wrapper_namespace=pbzero:' + cpp_out_dir]
  elif target.proto_plugin == 'cppgen':
    suffixes = ['gen']
    plugin = create_modules_from_target(blueprint, gn, cppgen_plugin)
    tools.add(plugin.name)
    cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
    cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
  elif target.proto_plugin == 'ipc':
    suffixes = ['ipc']
    plugin = create_modules_from_target(blueprint, gn, ipc_plugin)
    tools.add(plugin.name)
    cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
    cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
  else:
    raise Error('Unsupported proto plugin: %s' % target.proto_plugin)

  cmd += ['$(in)']
  source_module.cmd = ' '.join(cmd)
  header_module.cmd = source_module.cmd
  source_module.tools = tools
  header_module.tools = tools

  for sfx in suffixes:
    source_module.out.update('%s/%s' %
                             (tree_path, src.replace('.proto', '.%s.cc' % sfx))
                             for src in source_module.srcs)
    header_module.out.update('%s/%s' %
                             (tree_path, src.replace('.proto', '.%s.h' % sfx))
                             for src in header_module.srcs)
  return source_module


def create_amalgamated_sql_module(blueprint, gn, target):
  bp_module_name = label_to_module_name(target.name)

  def find_arg(name):
    for i, arg in enumerate(target.args):
      if arg.startswith(f'--{name}'):
        return target.args[i + 1]

  namespace = find_arg('namespace')
  root_dir = gn_utils.label_to_path(find_arg('root-dir'))

  module = Module('genrule', bp_module_name, target.name)
  module.tool_files = [
      'tools/gen_amalgamated_sql.py',
  ]
  module.cmd = ' '.join([
      '$(location tools/gen_amalgamated_sql.py)',
      f'--namespace={namespace}',
      f'--root-dir={root_dir}',
      '--cpp-out=$(out)',
      '$(in)',
  ])
  module.genrule_headers.add(module.name)
  module.out.update(target.outputs)

  for dep in target.source_set_deps:
    module.srcs.update(
        [gn_utils.label_to_path(src) for src in gn.get_target(dep).inputs])
  blueprint.add_module(module)
  return module


def create_cc_proto_descriptor_module(blueprint, target):
  bp_module_name = label_to_module_name(target.name)
  module = Module('genrule', bp_module_name, target.name)
  module.tool_files = [
      'tools/gen_cc_proto_descriptor.py',
  ]
  module.cmd = ' '.join([
      '$(location tools/gen_cc_proto_descriptor.py)', '--gen_dir=$(genDir)',
      '--cpp_out=$(out)', '$(in)'
  ])
  module.genrule_headers.add(module.name)
  module.srcs.update(
      ':' + label_to_module_name(dep) for dep in target.proto_deps)
  module.srcs.update(
      gn_utils.label_to_path(src)
      for src in target.inputs
      if "tmp.gn_utils" not in src)
  module.out.update(target.outputs)
  blueprint.add_module(module)
  return module


def create_gen_version_module(blueprint, target, bp_module_name):
  module = Module('genrule', bp_module_name, gn_utils.GEN_VERSION_TARGET)
  script_path = gn_utils.label_to_path(target.script)
  module.genrule_headers.add(bp_module_name)
  module.tool_files = [script_path]
  module.out.update(target.outputs)
  module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
  module.cmd = ' '.join([
      'python3 $(location %s)' % script_path, '--no_git',
      '--changelog=$(location CHANGELOG)', '--cpp_out=$(out)'
  ])
  blueprint.add_module(module)
  return module


def create_proto_group_modules(blueprint, gn, module_name, target_names):
  # TODO(lalitm): today, we're only adding a Java lite module because that's
  # the only one used in practice. In the future, if we need other target types
  # (e.g. C++, Java full etc.) add them here.
  bp_module_name = label_to_module_name(module_name) + '_java_protos'
  module = Module('java_library', bp_module_name, bp_module_name)
  module.comment = f'''GN: [{', '.join(target_names)}]'''
  module.proto = {'type': 'lite', 'canonical_path_from_root': False}

  for name in target_names:
    target = gn.get_target(name)
    module.srcs.update(gn_utils.label_to_path(src) for src in target.sources)
    for dep_label in target.transitive_proto_deps:
      dep = gn.get_target(dep_label)
      module.srcs.update(gn_utils.label_to_path(src) for src in dep.sources)

  blueprint.add_module(module)


def _get_cflags(target):
  cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
  cflags |= set("-D%s" % define
                for define in target.defines
                if re.match(define_allowlist, define))
  return cflags


def create_modules_from_target(blueprint, gn, gn_target_name):
  """Generate module(s) for a given GN target.

    Given a GN target name, generate one or more corresponding modules into a
    blueprint. The only case when this generates >1 module is proto libraries.

    Args:
        blueprint: Blueprint instance which is being generated.
        gn: gn_utils.GnParser object.
        gn_target_name: GN target for module generation.
    """
  bp_module_name = label_to_module_name(gn_target_name)
  if bp_module_name in blueprint.modules:
    return blueprint.modules[bp_module_name]
  target = gn.get_target(gn_target_name)

  name_without_toolchain = gn_utils.label_without_toolchain(target.name)
  if target.type == 'executable':
    if target.toolchain == gn_utils.HOST_TOOLCHAIN:
      module_type = 'cc_binary_host'
    elif target.testonly:
      module_type = 'cc_test'
    else:
      module_type = 'cc_binary'
    module = Module(module_type, bp_module_name, gn_target_name)
  elif target.type == 'static_library':
    module = Module('cc_library_static', bp_module_name, gn_target_name)
  elif target.type == 'shared_library':
    module = Module('cc_library_shared', bp_module_name, gn_target_name)
  elif target.type == 'source_set':
    module = Module('filegroup', bp_module_name, gn_target_name)
  elif target.type == 'group':
    # "group" targets are resolved recursively by gn_utils.get_target().
    # There's nothing we need to do at this level for them.
    return None
  elif target.type == 'proto_library':
    module = create_proto_modules(blueprint, gn, target)
    if module is None:
      return None
  elif target.type == 'action':
    if target.custom_action_type == 'sql_amalgamation':
      return create_amalgamated_sql_module(blueprint, gn, target)

    if target.custom_action_type == 'cc_proto_descriptor':
      module = create_cc_proto_descriptor_module(blueprint, target)
    elif name_without_toolchain == gn_utils.GEN_VERSION_TARGET:
      module = create_gen_version_module(blueprint, target, bp_module_name)
    else:
      raise Error('Unhandled action: {}'.format(target.name))
  else:
    raise Error('Unknown target %s (%s)' % (target.name, target.type))

  blueprint.add_module(module)
  module.host_supported = (name_without_toolchain in target_host_supported)
  module.vendor_available = (name_without_toolchain in target_vendor_available)
  module.init_rc = target_initrc.get(target.name, [])
  module.srcs.update(
      gn_utils.label_to_path(src)
      for src in target.sources
      if is_supported_source_file(src))

  if target.type in gn_utils.LINKER_UNIT_TYPES:
    module.cflags.update(_get_cflags(target))

  module_is_compiled = module.type not in ('genrule', 'filegroup')
  if module_is_compiled:
    # Don't try to inject library/source dependencies into genrules or
    # filegroups because they are not compiled in the traditional sense.
    module.defaults = [defaults_module]
    for lib in target.libs:
      # Generally library names should be mangled as 'libXXX', unless they
      # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++ / NDK
      # libraries (e.g. "android.hardware.power.stats-V1-cpp")
      android_lib = lib if '@' in lib or "-cpp" in lib or "-ndk" in lib \
        else 'lib' + lib
      if lib in shared_library_allowlist:
        module.add_android_shared_lib(android_lib)
      if lib in static_library_allowlist:
        module.add_android_static_lib(android_lib)

  # If the module is a static library, export all the generated headers.
  if module.type == 'cc_library_static':
    module.export_generated_headers = module.generated_headers

  # Merge in additional hardcoded arguments.
  for key, add_val in additional_args.get(module.name, []):
    curr = getattr(module, key)
    if add_val and isinstance(add_val, set) and isinstance(curr, set):
      curr.update(add_val)
    elif isinstance(add_val, str) and (not curr or isinstance(curr, str)):
      setattr(module, key, add_val)
    elif isinstance(add_val, bool) and (not curr or isinstance(curr, bool)):
      setattr(module, key, add_val)
    elif isinstance(add_val, dict) and isinstance(curr, dict):
      curr.update(add_val)
    elif isinstance(add_val, dict) and isinstance(curr, Target):
      curr.__dict__.update(add_val)
    else:
      raise Error('Unimplemented type %r of additional_args: %r' %
                  (type(add_val), key))

  # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
  all_deps = target.deps | target.source_set_deps | target.transitive_proto_deps
  for dep_name in all_deps:
    # If the dependency refers to a library which we can replace with an
    # Android equivalent, stop recursing and patch the dependency in.
    # Don't recurse into //buildtools, builtin_deps are intercepted at
    # the //gn:xxx level.
    if dep_name.startswith('//buildtools'):
      continue

    # Ignore the dependency on the gen_buildflags genrule. That is run
    # separately in this generator and the generated file is copied over
    # into the repo (see usage of |buildflags_dir| in this script).
    if dep_name.startswith(gn_utils.BUILDFLAGS_TARGET):
      continue

    dep_module = create_modules_from_target(blueprint, gn, dep_name)

    # For filegroups and genrule, recurse but don't apply the deps.
    if not module_is_compiled:
      continue

    # |builtin_deps| override GN deps with Android-specific ones. See the
    # config in the top of this file.
    if gn_utils.label_without_toolchain(dep_name) in builtin_deps:
      builtin_deps[gn_utils.label_without_toolchain(dep_name)](module)
      continue

    # Don't recurse in any other //gn dep if not handled by builtin_deps.
    if dep_name.startswith('//gn:'):
      continue

    if dep_module is None:
      continue
    if dep_module.type == 'cc_library_shared':
      module.shared_libs.add(dep_module.name)
    elif dep_module.type == 'cc_library_static':
      module.static_libs.add(dep_module.name)
    elif dep_module.type == 'filegroup':
      module.srcs.add(':' + dep_module.name)
    elif dep_module.type == 'genrule':
      module.generated_headers.update(dep_module.genrule_headers)
      module.srcs.update(dep_module.genrule_srcs)
      module.shared_libs.update(dep_module.genrule_shared_libs)
    elif dep_module.type == 'cc_binary':
      continue  # Ignore executables deps (used by cmdline integration tests).
    else:
      raise Error('Unknown dep %s (%s) for target %s' %
                  (dep_module.name, dep_module.type, module.name))

  return module


def create_blueprint_for_targets(gn, desc, targets):
  """Generate a blueprint for a list of GN targets."""
  blueprint = Blueprint()

  # Default settings used by all modules.
  defaults = Module('cc_defaults', defaults_module, '//gn:default_deps')

  # We have to use include_dirs passing the path relative to the android tree.
  # This is because: (i) perfetto_cc_defaults is used also by
  # test/**/Android.bp; (ii) if we use local_include_dirs instead, paths
  # become relative to the Android.bp that *uses* cc_defaults (not the one
  # that defines it).s
  defaults.include_dirs = {
      tree_path, tree_path + '/include', tree_path + '/' + buildflags_dir,
      tree_path + '/src/profiling/memory/include'
  }
  defaults.cflags = [
      '-Wno-error=return-type',
      '-Wno-sign-compare',
      '-Wno-sign-promo',
      '-Wno-unused-parameter',
      '-fvisibility=hidden',
      '-O2',
  ]
  defaults.user_debug_flag = True
  defaults.lto = True

  blueprint.add_module(defaults)
  for target in targets:
    create_modules_from_target(blueprint, gn, target)
  return blueprint


def main():
  parser = argparse.ArgumentParser(
      description='Generate Android.bp from a GN description.')
  parser.add_argument(
      '--check-only',
      help='Don\'t keep the generated files',
      action='store_true')
  parser.add_argument(
      '--desc',
      help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"'
  )
  parser.add_argument(
      '--extras',
      help='Extra targets to include at the end of the Blueprint file',
      default=os.path.join(gn_utils.repo_root(), 'Android.bp.extras'),
  )
  parser.add_argument(
      '--output',
      help='Blueprint file to create',
      default=os.path.join(gn_utils.repo_root(), 'Android.bp'),
  )
  parser.add_argument(
      'targets',
      nargs=argparse.REMAINDER,
      help='Targets to include in the blueprint (e.g., "//:perfetto_tests")')
  args = parser.parse_args()

  if args.desc:
    with open(args.desc) as f:
      desc = json.load(f)
  else:
    desc = gn_utils.create_build_description(gn_args)

  gn = gn_utils.GnParser(desc)
  blueprint = create_blueprint_for_targets(gn, desc, args.targets or
                                           default_targets)
  project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
  tool_name = os.path.relpath(os.path.abspath(__file__), project_root)

  # TODO(primiano): enable this on Android after the TODO in
  # perfetto_component.gni is fixed.
  # Check for ODR violations
  # for target_name in default_targets:
  # checker = gn_utils.ODRChecker(gn, target_name)

  # Add any proto groups to the blueprint.
  for l_name, t_names in proto_groups.items():
    create_proto_group_modules(blueprint, gn, l_name, t_names)

  output = [
      """// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file is automatically generated by %s. Do not edit.
""" % (tool_name)
  ]
  blueprint.to_string(output)
  with open(args.extras, 'r') as r:
    for line in r:
      output.append(line.rstrip("\n\r"))

  out_files = []

  # Generate the Android.bp file.
  out_files.append(args.output + '.swp')
  with open(out_files[-1], 'w') as f:
    f.write('\n'.join(output))
    # Text files should have a trailing EOL.
    f.write('\n')

  # Generate the perfetto_build_flags.h file.
  out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
  gn_utils.gen_buildflags(gn_args, out_files[-1])

  # Either check the contents or move the files to their final destination.
  return gn_utils.check_or_commit_generated_files(out_files, args.check_only)


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