#!/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" ]
  check_includes = {check_includes}
}}"""

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

TARGET_ALLOW_LIST = set([
    'grpc_cpp_plugin',
])

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

DEP_DENYLIST = set([
    'cares',
])


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')
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 bazel_label_to_gn_dep(dep: str) -> str:
  if dep == 'protobuf':
    return '..:protobuf_full'
  if dep == 'protoc':
    return '..:protoc_lib'
  if dep == 'z':
    return '..:zlib'
  return ':' + bazel_label_to_gn_target(dep)


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_asm']]
    deps = [
        bazel_label_to_gn_dep(dep)
        for dep in lib.get('deps', [])
        if dep not in DEP_DENYLIST
    ]
    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']),
        check_includes='false' if lib['name'] == 'upb_json_lib' or
        lib['name'] == 'upb_textformat_lib' else 'true')
    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 = [
        bazel_label_to_gn_dep(dep)
        for dep in bin.get('deps', [])
        if dep not in DEP_DENYLIST
    ]
    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',
        check_includes='true')
    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 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())
