#!/usr/bin/env python3
# Copyright (C) 2023 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.

import json
import os
import subprocess
import sys
from typing import Any, Dict, List
import yaml

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

GRPC_GN_HEADER = '''
#
# DO NOT EDIT. AUTOGENERATED file
#
# This file is generated with the command:
# tools/gen_grpc_build_gn.py > buildtools/grpc/BUILD.gn
#

import("../../gn/perfetto.gni")

# Prevent the gRPC from being depended upon without explicitly being opted in.
assert(enable_perfetto_grpc)

# BoringSSL has assembly code which is tied to platform-specific. For now, we
# only care about Linux x64 so assert this as the case.
assert(is_linux && current_cpu == "x64")
'''

TARGET_TEMPLATE = """
{target_type}("{name}") {{
  sources = {srcs}
  public_deps = {deps}
  public_configs = ["..:{config_name}"]
  configs -= [ "//gn/standalone:extra_warnings" ]
}}"""

LIBRARY_IGNORE_LIST = set([
    'grpcpp_channelz',
    'grpc++_reflection',
    'benchmark_helpers',
    'boringssl_test_util',
])

TARGET_ALLOW_LIST = set([
    'grpc_cpp_plugin',
])

STATIC_LIBRARY_TARGETS = set([
    'upb',
    're2',
    'boringssl',
    'grpc++',
])


def grpc_relpath(*segments: str) -> str:
  '''From path segments to GRPC root, returns the absolute path.'''
  return os.path.join(ROOT_DIR, 'buildtools', 'grpc', 'src', *segments)


GRPC_BUILD_YAML = grpc_relpath('build_autogenerated.yaml')
ABSL_GEN_BUILD_YAML = grpc_relpath('src', 'abseil-cpp', 'gen_build_yaml.py')
UPB_GEN_BUILD_YAML = grpc_relpath('src', 'upb', 'gen_build_yaml.py')
RE2_GEN_BUILD_YAML = grpc_relpath('src', 're2', 'gen_build_yaml.py')
BSSL_GEN_BUILD_YAML = grpc_relpath('src', 'boringssl', 'gen_build_yaml.py')


def gen_grpc_dep_yaml(gen_path: str) -> Dict[str, Any]:
  '''Invokes a gen_build_yaml.py file for creating YAML for gRPC deps.'''
  return yaml.safe_load(subprocess.check_output(['python3', gen_path]))


def bazel_label_to_gn_target(dep: str) -> str:
  '''Converts a Bazel label name into a gn target name.'''
  if dep == 'libssl':
    return 'boringssl'
  return dep.replace('/', '_').replace(':', '_')


def get_deps_for_target(target: str) -> List[str]:
  if target == 'grpc_plugin_support':
    return ['..:protoc_lib']
  if target == 'grpc':
    return [':re2', '../../gn:zlib']
  if target == 'grpc_authorization_provider':
    return [':re2']
  return []


def get_library_target_type(target: str) -> str:
  if target in STATIC_LIBRARY_TARGETS:
    return 'static_library'
  return 'source_set'


def yaml_to_gn_targets(desc: Dict[str, Any], build_types: list[str],
                       config_name: str) -> List[str]:
  '''Given a gRPC YAML description of the build graph, generates GN targets.'''
  out = []
  for lib in desc['libs']:
    if lib['build'] not in build_types:
      continue
    if lib['name'] in LIBRARY_IGNORE_LIST:
      continue
    srcs = [f'src/{file}' for file in lib['src'] + lib['headers']]
    if 'asm_src' in lib:
      srcs += [f'src/{file}' for file in lib['asm_src']['crypto_linux_x86_64']]
    deps = [f':{bazel_label_to_gn_target(dep)}' for dep in lib.get('deps', [])
           ] + get_deps_for_target(lib['name'])
    library_target = TARGET_TEMPLATE.format(
        name=bazel_label_to_gn_target(lib['name']),
        config_name=config_name,
        srcs=json.dumps(srcs),
        deps=json.dumps(deps),
        target_type=get_library_target_type(lib['name']))
    out.append(library_target)

  for bin in desc.get('targets', []):
    if bin['build'] not in build_types:
      continue
    if bin['name'] not in TARGET_ALLOW_LIST:
      continue
    srcs = json.dumps([f'src/{file}' for file in bin['src'] + bin['headers']])
    deps = [f':{bazel_label_to_gn_target(dep)}' for dep in bin.get('deps', [])
           ] + get_deps_for_target(bin['name'])
    binary_target = TARGET_TEMPLATE.format(
        name=bazel_label_to_gn_target(bin['name']),
        config_name=config_name,
        srcs=srcs,
        deps=json.dumps(deps),
        target_type='executable')
    out.append(binary_target)
  return out


def main():
  out: List[str] = []

  # Generate absl rules
  absl_yaml = gen_grpc_dep_yaml(ABSL_GEN_BUILD_YAML)
  out.extend(yaml_to_gn_targets(absl_yaml, ['private'], 'grpc_absl_config'))

  # Generate upb rules
  upb_yaml = gen_grpc_dep_yaml(UPB_GEN_BUILD_YAML)
  out.extend(yaml_to_gn_targets(upb_yaml, ['all'], 'grpc_upb_config'))

  # Generate re2 rules
  re2_yaml = gen_grpc_dep_yaml(RE2_GEN_BUILD_YAML)
  out.extend(yaml_to_gn_targets(re2_yaml, ['private'], 'grpc_re2_config'))

  # Generate boringssl rules
  boringssl_yaml = gen_grpc_dep_yaml(BSSL_GEN_BUILD_YAML)
  out.extend(
      yaml_to_gn_targets(boringssl_yaml, ['private'], 'grpc_boringssl_config'))

  # Generate grpc rules
  with open(GRPC_BUILD_YAML, 'r', encoding='utf-8') as f:
    grpc_yaml = yaml.safe_load(f.read())
  out.extend(
      yaml_to_gn_targets(grpc_yaml, ['all', 'protoc'], 'grpc_internal_config'))

  print(GRPC_GN_HEADER)
  print('\n'.join(out))
  return 0


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