#!/usr/bin/env python
# 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',
    '//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',
]

# 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 += [
    '//tools/trace_to_text:trace_to_text(%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',
    '//protos/perfetto/trace:perfetto_trace_protos',
    '//src/trace_processor:trace_processor_shell',
]

# 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.power.stats@1.0',
    'base',
    'binder',
    'cutils',
    'hidlbase',
    'hidltransport',
    'hwbinder',
    'incident',
    'log',
    'services',
    'statssocket',
    '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)$'

# Shared libraries which are not in PDK.
library_not_in_pdk = {
    'libandroid',
    'libservices',
}

# 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 + '**/*'
    else:
      yield line


# Additional arguments to apply to Android.bp rules.
additional_args = {
    'heapprofd_client_api': [
        ('include_dirs', {'bionic/libc'}),
        ('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'),
    ],
    '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'),
        ('stl', 'libc++_static'),
    ],
    'perfetto_unittests': [
        ('data', set(enumerate_data_deps())),
        ('include_dirs', {'bionic/libc/kernel'}),
    ],
    'perfetto_integrationtests': [
      # heapprofd_end_to_end needs root to set a system property.
      ('require_root', True),
      ('test_suites', {'general-tests'}),
    ],
    'traced_probes': [
        ('required', {'libperfetto_android_internal',
                      'trigger_perfetto',
                      'traced_perf'}),
    ],
    'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
    'trace_processor_shell': [
      ('host', {
        'stl': 'libc++_static'
      }),
    ],
    'libperfetto_client_experimental': [
      ('apex_available', {
        '//apex_available:platform',
        'com.android.art',
        'com.android.art.debug'}),
      ('shared_libs', {'liblog'}),
    ],
    'perfetto_trace_protos': [
      ('apex_available', {
        '//apex_available:platform',
        'com.android.art',
        'com.android.art.debug'}),
    ],
}


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')


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')
  elif module.host_supported:
    # Copy what the sqlite3 command line tool does.
    module.android.shared_libs.add('libsqlite')
    module.android.shared_libs.add('libandroidicu')
    module.android.shared_libs.add('liblog')
    module.android.shared_libs.add('libutils')
    module.host.static_libs.add('libsqlite')
  else:
    module.shared_libs.add('libsqlite')
    module.shared_libs.add('libandroidicu')
    module.shared_libs.add('liblog')
    module.shared_libs.add('libutils')


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 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, bool):
    output.append('  %s: true,' % name)
    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.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')

    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.tools = set()
    self.cmd = None
    self.host_supported = 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()
    # 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.require_root = None
    self.test_suites = set()

  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, 'tools')
    self._output_field(output, 'cmd', sort=False)
    self._output_field(output, 'host_supported')
    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, 'version_script')
    self._output_field(output, 'require_root')
    self._output_field(output, 'test_suites')

    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('  },')

    disable_pdk = any(name in library_not_in_pdk for name in self.shared_libs)
    if self.user_debug_flag or disable_pdk:
      output.append('  product_variables: {')
      if disable_pdk:
        output.append('    pdk: {')
        output.append('      enabled: false,')
        output.append('    },')
      if self.user_debug_flag:
        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
  # "trace_to_text" 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.
    target_queue = collections.deque([target.name])
    seen_targets = set()
    while target_queue:
      dep = target_queue.popleft()
      if dep in seen_targets:
        continue
      seen_targets.add(dep)

      current_target = gn.get_target(dep)
      descriptor_module.srcs.update(
          gn_utils.label_to_path(src) for src in current_target.sources)
      target_queue.extend(current_target.proto_deps)

    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_merged_sql_metrics_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_merged_sql_metrics.py',
  ]
  module.cmd = ' '.join([
      '$(location tools/gen_merged_sql_metrics.py)',
      '--cpp_out=$(out)',
      '$(in)',
  ])
  module.genrule_headers.add(module.name)
  module.out.update(target.outputs)
  module.srcs.update(gn_utils.label_to_path(src) for src in target.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.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',
        '--cpp_out=$(out)'
  ])
  blueprint.add_module(module)
  return 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)
  export_include_dirs = {'include', buildflags_dir}

  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)
    module.export_include_dirs = export_include_dirs
  elif target.type == 'shared_library':
    module = Module('cc_library_shared', bp_module_name, gn_target_name)
    module.export_include_dirs = export_include_dirs
  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 'gen_merged_sql_metrics' in target.name:
      module = create_merged_sql_metrics_module(blueprint, target)
    elif re.match('.*gen_cc_.*_descriptor$', target.name):
      module = create_cc_proto_descriptor_module(blueprint, target)
    elif target.type == 'action' and gn_utils.label_without_toolchain(
        target.name) == 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 = (gn_utils.label_without_toolchain(target.name) in
                           target_host_supported)
  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).
      android_lib = lib if '@' 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 of additional_args: %r' % key)

  # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
  for dep_name in target.deps | target.source_set_deps | target.proto_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
  }
  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)
  gn = gn_utils.GnParser(desc)
  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)

  # 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)

  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.
""" % (__file__)
  ]
  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())
