#!/usr/bin/env python3
# Copyright (C) 2018 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
# BUILD file for the Bazel 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 Bazel
# build rules.

from __future__ import print_function
import argparse
import json
import os
import re
import sys
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Union

from gn_utils import GnParser
import gn_utils

from compat import itervalues, iteritems, basestring

# Visibility option for targets which we want an allowlist of public targets
# which can depend on it.
ALLOWLIST_PUBLIC_VISIBILITY = 'PERFETTO_CONFIG.public_visibility'

# Arguments for the GN output directory.
# host_os="linux" is to generate the right build files from Mac OS.
gn_args = ' '.join([
    'host_os="linux"',
    'is_debug=false',
    'is_perfetto_build_generator=true',
    'monolithic_binaries=true',
    'target_os="linux"',
    'enable_perfetto_heapprofd=false',
    'enable_perfetto_traced_perf=false',
    'perfetto_force_dcheck="off"',
    'enable_perfetto_llvm_demangle=true',
])

# Default targets to translate to the blueprint file.

# These targets will be exported with public visibility in the generated BUILD.
public_targets = [
    '//:libperfetto_client_experimental',
    '//src/perfetto_cmd:perfetto',
    '//src/traced/probes:traced_probes',
    '//src/traced/service:traced',
    '//src/trace_processor:trace_processor_shell',
    '//src/trace_processor:trace_processor',
    '//src/traceconv:traceconv',
    '//src/traceconv:libpprofbuilder',
]

# These targets are required by internal build rules but don't need to be
# exported publicly.
default_targets = [
    '//src/base:perfetto_base_default_platform',
    '//src/ipc:perfetto_ipc',
    '//src/ipc/protoc_plugin:ipc_plugin',
    '//src/protozero:protozero',
    '//src/protozero/protoc_plugin:cppgen_plugin',
    '//src/protozero/protoc_plugin:protozero_plugin',
    '//src/tools/proto_filter:proto_filter',
    '//src/tools/proto_merger:proto_merger',
    '//src/trace_processor/rpc:trace_processor_rpc',
    '//test:client_api_example',
] + public_targets

# Proto target groups which will be made public.
proto_groups = {
    'config': {
        'sources': ['//protos/perfetto/config:source_set'],
        'visibility': ['//visibility:public'],
    },
    'trace': {
        'sources': [
            '//protos/perfetto/trace:non_minimal_source_set',
            '//protos/perfetto/trace:minimal_source_set'
        ],
        'visibility': ALLOWLIST_PUBLIC_VISIBILITY,
    },
    'metrics': {
        'sources': ['//protos/perfetto/metrics:source_set',],
        'visibility': ['//visibility:public'],
    },
    'chromium': {
        'sources': ['//protos/third_party/chromium:source_set',],
        'visibility': ALLOWLIST_PUBLIC_VISIBILITY,
    },
    'chrome_metrics': {
        'sources': ['//protos/perfetto/metrics/chrome:source_set',],
        'visibility': ALLOWLIST_PUBLIC_VISIBILITY,
    },
    'trace_processor': {
        'sources': ['//protos/perfetto/trace_processor:source_set',],
        'visibility': [],
    },
}

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

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

# Internal equivalents for third-party libraries that the upstream project
# depends on.
external_deps = {
    '//gn:default_deps': [],
    '//gn:base_platform': ['PERFETTO_CONFIG.deps.base_platform'],
    '//gn:jsoncpp': ['PERFETTO_CONFIG.deps.jsoncpp'],
    '//gn:linenoise': ['PERFETTO_CONFIG.deps.linenoise'],
    '//gn:protobuf_full': ['PERFETTO_CONFIG.deps.protobuf_full'],
    '//gn:protobuf_lite': ['PERFETTO_CONFIG.deps.protobuf_lite'],
    '//gn:protoc_lib': ['PERFETTO_CONFIG.deps.protoc_lib'],
    '//gn:protoc': ['PERFETTO_CONFIG.deps.protoc'],
    '//gn:sqlite': [
        'PERFETTO_CONFIG.deps.sqlite',
        'PERFETTO_CONFIG.deps.sqlite_ext_percentile'
    ],
    '//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'],
    '//gn:llvm_demangle': ['PERFETTO_CONFIG.deps.llvm_demangle'],
    '//src/trace_processor:demangle': ['PERFETTO_CONFIG.deps.demangle_wrapper'],
    gn_utils.GEN_VERSION_TARGET: ['PERFETTO_CONFIG.deps.version_header'],
}

# These are Python targets which are exposed with public visibility.
public_python_targets = [
    '//python:batch_trace_processor',
    '//python:trace_processor_py',
]

# These are Python targets which are exposed by default.
default_python_targets = [
    '//python:batch_trace_processor',
    '//python:experimental_slice_breakdown_bin',
    '//python:trace_processor_table_generator',
    '//python:trace_processor_py_example',
]

# Internal equivalents for third-party Python libraries.
external_python_deps: Dict[str, List[str]] = {
    '//gn:pandas_py': ['PERFETTO_CONFIG.deps.pandas_py'],
    '//gn:protobuf_py': ['PERFETTO_CONFIG.deps.protobuf_py'],
    '//gn:tp_vendor_py': ['PERFETTO_CONFIG.deps.tp_vendor_py'],
}


def gen_version_header(target):
  label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
  label.srcs += [gn_utils.label_to_path(x) for x in sorted(target.inputs)]
  label.outs += target.outputs
  label.cmd = r'$(location gen_version_header_py)'
  label.cmd += r' --cpp_out=$@ --changelog=$(location CHANGELOG)'
  label.tools += [':gen_version_header_py']
  return [label]


custom_actions = {
    gn_utils.GEN_VERSION_TARGET: gen_version_header,
}

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


class PythonBuildGenerator:
  '''Generator of the BUILD file in the python folder.

  This code is split into its own class to avoid polluting
  the generation of the main build file with Python related
  content.
  '''

  def populate_python_deps(self, target: GnParser.Target, label: 'BazelLabel'):
    '''Populates deps for a GN target into Bazel Python label.'''
    for dep in sorted(target.non_proto_or_source_set_deps()):
      if dep.name in external_python_deps:
        assert (isinstance(external_python_deps[dep.name], list))
        label.external_deps += external_python_deps[dep.name]
      else:
        label.deps += [':' + get_bazel_python_label_name(dep.name)]

  def python_label_to_path(self, gn_name: str):
    """Converts a Python GN path label into a Bazel path."""
    return re.sub(r'^python/', '', gn_utils.label_to_path(gn_name))

  def python_data_to_path(self, gn_name: str):
    """Converts a Python GN data label into a Bazel data label."""
    return re.sub(r'^\.\.(.*)', r'PERFETTO_CONFIG.root + "\1"', gn_name)

  def gen_python_library(self, target: GnParser.Target):
    """Creates a Bazel target for a Python library GN target."""
    label = BazelLabel(
        get_bazel_python_label_name(target.name), 'perfetto_py_library')
    label.comment = target.name
    label.srcs += (self.python_label_to_path(x) for x in target.sources)
    label.data += (self.python_data_to_path(x) for x in target.data)
    self.populate_python_deps(target, label)
    if target.name in public_python_targets:
      label.visibility = ['//visibility:public']
    return [label]

  def gen_python_binary(self, target: GnParser.Target):
    """Creates a Bazel target for a Python binary GN target."""
    label = BazelLabel(
        get_bazel_python_label_name(target.name), 'perfetto_py_binary')
    label.comment = target.name
    label.srcs += (self.python_label_to_path(x) for x in target.sources)
    label.data += (self.python_data_to_path(x) for x in target.data)
    label.main = target.python_main
    label.python_version = 'PY3'
    if target.name in public_python_targets:
      label.visibility = ['//visibility:public']

    self.populate_python_deps(target, label)
    return [label]

  def gen_target(self, gn_target: GnParser.Target):
    """Creates a Bazel target for a Python GN target."""
    assert (gn_target.type == 'action')
    if gn_target.name in external_python_deps:
      return []
    if gn_target.custom_action_type == 'python_library':
      return self.gen_python_library(gn_target)
    if gn_target.custom_action_type == 'python_binary':
      return self.gen_python_binary(gn_target)
    assert (False)

  def gen_target_str(self, gn_target: GnParser.Target):
    """Creates a Bazel target string for a Python GN target."""
    return ''.join(str(x) for x in self.gen_target(gn_target))

  def generate(self, gn_desc):
    """Creates a Python BUILD file for the GN description."""
    gn = gn_utils.GnParser(gn_desc)
    project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
    tool_name = os.path.relpath(os.path.abspath(__file__), project_root)
    res = '''
# Copyright (C) 2022 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 {}. Do not edit.

load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
load(
    "@perfetto//bazel:rules.bzl",
    "perfetto_py_binary",
    "perfetto_py_library",
)

licenses(["notice"])

package(default_visibility = [PERFETTO_CONFIG.root + ":__subpackages__"])

'''.format(tool_name).lstrip()

    # Find all the targets in the //python folder.
    for target_name in default_python_targets:
      target = gn.get_target(target_name)
      res += self.gen_target_str(target)

    # Generate all the intermediate targets.
    for target in sorted(itervalues(gn.all_targets)):
      if target.name in default_python_targets:
        continue
      res += self.gen_target_str(target)

    return res


class Error(Exception):
  pass


class BazelLabel(object):

  def __init__(self, name, type):
    self.comment: Optional[str] = None
    self.name = name
    self.type = type
    self.visibility: Union[List[str], str] = []
    self.srcs = []
    self.hdrs = []
    self.data = []
    self.deps = []
    self.external_deps = []
    self.tools = []
    self.outs = []
    self.exports = []
    self.main = None
    self.cmd: Optional[str] = None
    self.python_version: Optional[str] = None
    self.root_dir: Optional[str] = None
    self.namespace: Optional[str] = None

  def __lt__(self, other):
    if isinstance(other, self.__class__):
      return self.name < other.name
    raise TypeError(
        '\'<\' not supported between instances of \'%s\' and \'%s\'' %
        (type(self).__name__, type(other).__name__))

  def __str__(self):
    """Converts the object into a Bazel Starlark label."""
    res = ''
    res += ('# GN target: %s\n' % self.comment) if self.comment else ''
    res += '%s(\n' % self.type
    any_deps = len(self.deps) + len(self.external_deps) > 0
    ORD = [
        'name', 'srcs', 'hdrs', 'visibility', 'data', 'deps', 'outs', 'cmd',
        'tools', 'exports', 'main', 'python_version'
    ]
    hasher = lambda x: sum((99,) + tuple(ord(c) for c in x))
    key_sorter = lambda kv: ORD.index(kv[0]) if kv[0] in ORD else hasher(kv[0])
    for k, v in sorted(iteritems(self.__dict__), key=key_sorter):
      if k in ('type', 'comment',
               'external_deps') or v is None or (v == [] and
                                                 (k != 'deps' or not any_deps)):
        continue
      res += '    %s = ' % k
      if isinstance(v, basestring):
        if v.startswith('PERFETTO_CONFIG.'):
          res += '%s,\n' % v
        else:
          res += '"%s",\n' % v
      elif isinstance(v, bool):
        res += '%s,\n' % v
      elif isinstance(v, list):
        res += '[\n'
        if k == 'deps' and len(self.external_deps) > 1:
          indent = '           '
        else:
          indent = '    '
        for entry in sorted(v):
          if entry.startswith('PERFETTO_CONFIG.'):
            res += '%s    %s,\n' % (indent, entry)
          else:
            res += '%s    "%s",\n' % (indent, entry)
        res += '%s]' % indent
        if k == 'deps' and self.external_deps:
          res += ' + %s' % self.external_deps[0]
          for edep in self.external_deps[1:]:
            if isinstance(edep, list):
              res += ' + [\n'
              for inner_dep in edep:
                res += '        "%s",\n' % inner_dep
              res += '    ]'
            else:
              res += ' +\n%s%s' % (indent, edep)
        res += ',\n'
      else:
        raise Error('Unsupported value %s', type(v))
    res += ')\n\n'
    return res


def get_bazel_label_name(gn_name: str):
  """Converts a GN target name into a Bazel label name.

  If target is in the public target list, returns only the GN target name,
  e.g.: //src/ipc:perfetto_ipc -> perfetto_ipc

  Otherwise, in the case of an intermediate target, returns a mangled path.
  e.g.:  //include/perfetto/base:base -> include_perfetto_base_base.
  """
  if gn_name in default_targets:
    return gn_utils.label_without_toolchain(gn_name).split(':')[1]
  return gn_utils.label_to_target_name_with_path(gn_name)


def get_bazel_python_label_name(gn_name: str):
  """Converts a Python GN label into a Bazel label."""
  name = re.sub(r'^//python:?', '', gn_name)
  return gn_utils.label_to_target_name_with_path(name)


def get_bazel_proto_sources_label(target_name: str):
  """Converts a GN target name into a Bazel proto label name."""
  return re.sub('_(lite|zero|cpp|ipc|source_set|descriptor)$', '',
                get_bazel_label_name(target_name)) + '_protos'


def gen_proto_label(target: GnParser.Target):
  """ Generates the xx_proto_library label for proto targets."""
  assert (target.type == 'proto_library')

  sources_label_name = get_bazel_proto_sources_label(target.name)

  # For 'source_set' plugins, we don't want to generate any plugin-dependent
  # targets so just return the label of the proto sources only.
  if target.proto_plugin == 'source_set':
    sources_label = BazelLabel(sources_label_name, 'perfetto_proto_library')
    sources_label.comment = target.name
    assert (all(x.startswith('//') for x in target.sources))
    assert (all(x.endswith('.proto') for x in target.sources))
    sources_label.srcs = sorted([x[2:] for x in target.sources])  # Strip //.
    sources_label.deps = sorted([
        ':' + get_bazel_proto_sources_label(x.name)
        for x in target.transitive_proto_deps()
    ])

    # In Bazel, proto_paths are not a supported concept becauase strong
    # dependency checking is enabled. Instead, we need to depend on the target
    # which includes the proto we want to depend on.
    # For example, we include the proto_path |buildtools_protobuf_src| because
    # we want to depend on the "google/protobuf/descriptor.proto" proto file.
    # This will be exposed by the |protobuf_descriptor_proto| dep.
    if buildtools_protobuf_src in target.proto_paths:
      sources_label.external_deps = [
          'PERFETTO_CONFIG.deps.protobuf_descriptor_proto'
      ]

    sources_label.visibility = ['PERFETTO_CONFIG.proto_library_visibility']

    sources_label.exports = sorted(
        [':' + get_bazel_proto_sources_label(d) for d in target.proto_exports])
    return sources_label

  # For all other types of plugins, we need to generate
  if target.proto_plugin == 'proto':
    plugin_label_type = 'perfetto_cc_proto_library'
  elif target.proto_plugin == 'protozero':
    plugin_label_type = 'perfetto_cc_protozero_library'
  elif target.proto_plugin == 'cppgen':
    plugin_label_type = 'perfetto_cc_protocpp_library'
  elif target.proto_plugin == 'ipc':
    plugin_label_type = 'perfetto_cc_ipc_library'
  elif target.proto_plugin == 'descriptor':
    plugin_label_type = 'perfetto_proto_descriptor'
  else:
    raise Error('Unknown proto plugin: %s' % target.proto_plugin)
  plugin_label_name = get_bazel_label_name(target.name)
  plugin_label = BazelLabel(plugin_label_name, plugin_label_type)
  plugin_label.comment = target.name

  # When using the plugins we need to pass down also the transitive deps.
  # For instance consider foo.proto including common.proto. The generated
  # foo.cc will #include "common.gen.h". Hence the generated cc_protocpp_library
  # rule need to pass down the dependency on the target that generates
  # common.gen.{cc,h}.
  if target.proto_plugin in ('cppgen', 'ipc', 'protozero'):
    plugin_label.deps += [
        ':' + get_bazel_label_name(x.name)
        for x in target.transitive_proto_deps()
    ]

  # Add any dependencies on source_set targets (i.e. targets containing proto
  # files). For descriptors, we will have an explicit edge between the
  # descriptor and source set wheras for other plugin types, this edge is
  # implicit.
  if target.proto_plugin == 'descriptor':
    plugin_label.deps += [
        ':' + get_bazel_proto_sources_label(x.name)
        for x in target.proto_deps()
    ]
  else:
    plugin_label.deps += [':' + sources_label_name]

  # Since the descriptor generates an explicit output file which can be
  # referenced by other targets, we specify a name for it.
  if target.proto_plugin == 'descriptor':
    plugin_label.outs = [plugin_label_name + '.bin']

  return plugin_label


def gen_proto_group_target(gn: GnParser, name: str, desc: Dict[str, Any]):
  # Get a recursive list of the proto_library targets rooted here which
  # have src.
  deps_set = set(desc['sources'])
  for target_name in desc['sources']:
    target = gn.get_target(target_name)
    deps_set.update(d.name for d in target.transitive_proto_deps())

  # First, create a root source set target which references all the child
  # source set targets. We publish this as well as depending on this in all
  # subsequent targets.
  sources_label = BazelLabel(name + '_proto', 'perfetto_proto_library')
  sources_label.deps = [
      ':' + get_bazel_proto_sources_label(name)
      for name in sorted(list(deps_set))
  ]
  sources_label.comment = f'''[{', '.join(desc['sources'])}]'''

  cc_label = BazelLabel(name + '_cc_proto', 'perfetto_cc_proto_library')
  cc_label.deps = [':' + sources_label.name]
  cc_label.comment = sources_label.comment

  java_label = BazelLabel(name + '_java_proto', 'perfetto_java_proto_library')
  java_label.deps = [':' + sources_label.name]
  java_label.comment = sources_label.comment

  lite_name = name + '_java_proto_lite'
  java_lite_label = BazelLabel(lite_name, 'perfetto_java_lite_proto_library')
  java_lite_label.deps = [':' + sources_label.name]
  java_lite_label.comment = sources_label.comment

  py_label = BazelLabel(name + '_py_pb2', 'perfetto_py_proto_library')
  py_label.deps = [':' + sources_label.name]
  py_label.comment = sources_label.comment

  visibility = desc['visibility']
  if visibility:
    sources_label.visibility = visibility
    cc_label.visibility = visibility
    java_label.visibility = visibility
    java_lite_label.visibility = visibility
    py_label.visibility = visibility

  return [sources_label, cc_label, java_label, java_lite_label, py_label]


def gen_cc_proto_descriptor(target: GnParser.Target):
  label = BazelLabel(
      get_bazel_label_name(target.name), 'perfetto_cc_proto_descriptor')
  label.comment = target.name
  label.deps += [
      ':' + get_bazel_label_name(x.name) for x in target.proto_deps()
  ]
  label.deps += [
      gn_utils.label_to_path(src)
      for src in target.inputs
      if "tmp.gn_utils" not in src
  ]

  label.outs += target.outputs
  return [label]


def gen_cc_amalgamated_sql(target: GnParser.Target):
  label = BazelLabel(
      get_bazel_label_name(target.name), 'perfetto_cc_amalgamated_sql')

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

  label.comment = target.name
  label.namespace = find_arg('namespace')

  label.deps += sorted(
      ':' + get_bazel_label_name(x.name) for x in target.transitive_deps)
  label.outs += target.outputs
  return [label]


def gen_sql_source_set(target: GnParser.Target):
  label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_filegroup')
  label.comment = target.name
  label.srcs += (gn_utils.label_to_path(x) for x in target.inputs)
  return [label]


def gen_cc_tp_tables(target: GnParser.Target):
  label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_cc_tp_tables')
  label.comment = target.name
  label.srcs += (gn_utils.label_to_path(x) for x in target.sources)
  label.deps += sorted(':' + get_bazel_label_name(x.name)
                       for x in target.transitive_deps
                       if x.name not in default_python_targets)
  label.outs += target.outputs
  return [label]


def gen_target(gn_target: GnParser.Target):
  if gn_target.type == 'proto_library':
    return [gen_proto_label(gn_target)]
  elif gn_target.type == 'action':
    if gn_target.name in custom_actions:
      return custom_actions[gn_target.name](gn_target)
    if gn_target.custom_action_type == 'sql_amalgamation':
      return gen_cc_amalgamated_sql(gn_target)
    if gn_target.custom_action_type == 'sql_source_set':
      return gen_sql_source_set(gn_target)
    if gn_target.custom_action_type == 'cc_proto_descriptor':
      return gen_cc_proto_descriptor(gn_target)
    if gn_target.custom_action_type == 'tp_tables':
      return gen_cc_tp_tables(gn_target)
    return []
  elif gn_target.type == 'group':
    return []
  elif gn_target.type == 'executable':
    bazel_type = 'perfetto_cc_binary'
  elif gn_target.type == 'shared_library':
    bazel_type = 'perfetto_cc_binary'
  elif gn_target.type == 'static_library':
    bazel_type = 'perfetto_cc_library'
  elif gn_target.type == 'source_set':
    bazel_type = 'perfetto_filegroup'
  elif gn_target.type == 'generated_file':
    return []
  else:
    raise Error('target type not supported: %s' % gn_target.type)

  label = BazelLabel(get_bazel_label_name(gn_target.name), bazel_type)
  label.comment = gn_target.name

  # Supporting 'public' on source_sets would require not converting them to
  # filegroups in bazel.
  if gn_target.public_headers:
    if bazel_type == 'perfetto_cc_library':
      label.hdrs += [x[2:] for x in gn_target.public_headers]
    else:
      raise Error('%s: \'public\' currently supported only for cc_library' %
                  gn_target.name)

  raw_srcs = [x[2:] for x in gn_target.sources]
  raw_srcs += [x[2:] for x in gn_target.inputs]
  if bazel_type == 'perfetto_cc_library':
    label.srcs += [x for x in raw_srcs if not x.startswith('include')]
    label.hdrs += [x for x in raw_srcs if x.startswith('include')]

    # Most Perfetto libraries cannot by dynamically linked as they would
    # cause ODR violations.
    label.__dict__['linkstatic'] = True
  else:
    label.srcs = raw_srcs

  if gn_target.name in public_targets:
    label.visibility = ['//visibility:public']

  if gn_target.type in gn_utils.LINKER_UNIT_TYPES:
    # |source_sets| contains the transitive set of source_set deps.
    for trans_dep in gn_target.transitive_source_set_deps():
      name = ':' + get_bazel_label_name(trans_dep.name)
      if name.startswith(
          ':include_perfetto_') and gn_target.type != 'executable':
        label.hdrs += [name]
      else:
        label.srcs += [name]
    for dep in sorted(gn_target.non_proto_or_source_set_deps()):
      dep_name = dep.name
      if dep_name.startswith('//gn:'):
        assert (dep_name in external_deps), dep

      # tp_tables produces a filegroup not a cc_lbirary so should end up srcs
      # not deps.
      if dep.custom_action_type == 'tp_tables':
        label.srcs += [':' + get_bazel_label_name(dep_name)]
      elif dep_name in external_deps:
        assert (isinstance(external_deps[dep_name], list))
        label.external_deps += external_deps[dep_name]
      else:
        label.deps += [':' + get_bazel_label_name(dep_name)]
    label.deps += [
        ':' + get_bazel_label_name(x.name)
        for x in gn_target.transitive_cpp_proto_deps()
    ]

  # All items starting with : need to be sorted to the end of the list.
  # However, Python makes specifying a comparator function hard so cheat
  # instead and make everything start with : sort as if it started with |
  # As | > all other normal ASCII characters, this will lead to all : targets
  # starting with : to be sorted to the end.
  label.srcs = sorted(label.srcs, key=lambda x: x.replace(':', '|'))

  label.deps = sorted(label.deps)
  label.hdrs = sorted(label.hdrs)
  return [label]


def gen_target_str(gn_target):
  return ''.join(str(x) for x in gen_target(gn_target))


def generate_build(gn_desc, targets, extras):
  gn = gn_utils.GnParser(gn_desc)
  project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
  tool_name = os.path.relpath(os.path.abspath(__file__), project_root)
  res = '''
# Copyright (C) 2019 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 {}. Do not edit.

load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
load(
    "@perfetto//bazel:rules.bzl",
    "perfetto_build_config_cc_library",
    "perfetto_cc_amalgamated_sql",
    "perfetto_cc_binary",
    "perfetto_cc_ipc_library",
    "perfetto_cc_library",
    "perfetto_cc_proto_descriptor",
    "perfetto_cc_proto_library",
    "perfetto_cc_protocpp_library",
    "perfetto_cc_protozero_library",
    "perfetto_cc_tp_tables",
    "perfetto_filegroup",
    "perfetto_genrule",
    "perfetto_go_proto_library",
    "perfetto_java_lite_proto_library",
    "perfetto_java_proto_library",
    "perfetto_proto_descriptor",
    "perfetto_proto_library",
    "perfetto_py_binary",
    "perfetto_py_library",
    "perfetto_py_proto_library",
    "perfetto_jspb_proto_library",
)

package(default_visibility = [PERFETTO_CONFIG.root + ":__subpackages__"])

licenses(["notice"])

exports_files(["NOTICE"])

'''.format(tool_name).lstrip()

  # Public targets need to be computed at the beginning (to figure out the
  # intermediate deps) but printed at the end (because declaration order matters
  # in Bazel).
  public_str = ''
  for target_name in sorted(public_targets):
    target = gn.get_target(target_name)
    public_str += gen_target_str(target)

  res += '''
# ##############################################################################
# Internal targets
# ##############################################################################

'''.lstrip()
  # Generate the other non-public targets.
  for target_name in sorted(set(default_targets) - set(public_targets)):
    target = gn.get_target(target_name)
    res += gen_target_str(target)

  # Generate all the intermediate targets.
  for target in sorted(itervalues(gn.all_targets)):
    if target.name in default_targets or target.name in gn.proto_libs:
      continue
    res += gen_target_str(target)

  res += '''
# ##############################################################################
# Proto libraries
# ##############################################################################

'''.lstrip()
  # Generate targets for proto groups.
  for l_name, t_desc in proto_groups.items():
    res += ''.join(str(x) for x in gen_proto_group_target(gn, l_name, t_desc))

  # For any non-source set and non-descriptor targets, ensure the source set
  # associated to that target is discovered.
  for target in sorted(itervalues(gn.all_targets)):
    plugin = target.proto_plugin
    if plugin is None or plugin == 'source_set' or plugin == 'descriptor':
      continue
    gn.get_target(re.sub('(lite|zero|cpp|ipc)$', 'source_set', target.name))

  # Generate targets for the transitive set of proto targets.
  labels = [
      l for target in sorted(itervalues(gn.proto_libs))
      for l in gen_target(target)
  ]
  res += ''.join(str(x) for x in sorted(labels))

  res += '''
# ##############################################################################
# Public targets
# ##############################################################################

'''.lstrip()
  res += public_str
  res += '# Content from BUILD.extras\n\n'
  res += extras

  # Check for ODR violations
  for target_name in default_targets:
    checker = gn_utils.ODRChecker(gn, target_name)

  return res


def main():
  parser = argparse.ArgumentParser(
      description='Generate BUILD 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(
      '--repo-root',
      help='Standalone Perfetto repository to generate a GN description',
      default=gn_utils.repo_root(),
  )
  parser.add_argument(
      '--extras',
      help='Extra targets to include at the end of the BUILD file',
      default=os.path.join(gn_utils.repo_root(), 'BUILD.extras'),
  )
  parser.add_argument(
      '--output',
      help='BUILD file to create',
      default=os.path.join(gn_utils.repo_root(), 'BUILD'),
  )
  parser.add_argument(
      '--output-python',
      help='Python BUILD file to create',
      default=os.path.join(gn_utils.repo_root(), 'python', 'BUILD'),
  )
  parser.add_argument(
      'targets',
      nargs=argparse.REMAINDER,
      help='Targets to include in the BUILD file (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, args.repo_root)

  out_files = []

  # Generate the main BUILD file.
  with open(args.extras, 'r') as extra_f:
    extras = extra_f.read()

  contents = generate_build(desc, args.targets or default_targets, extras)
  out_files.append(args.output + '.swp')
  with open(out_files[-1], 'w') as out_f:
    out_f.write(contents)

  # Generate the python BUILD file.
  python_gen = PythonBuildGenerator()
  python_contents = python_gen.generate(desc)
  out_files.append(args.output_python + '.swp')
  with open(out_files[-1], 'w') as out_f:
    out_f.write(python_contents)

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

  return gn_utils.check_or_commit_generated_files(out_files, args.check_only)


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