#!/usr/bin/env python3
# Copyright (C) 2026 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.
"""Emit a C++ header containing a constexpr std::array<uint8_t, N> blob.

Importable from other build-time codegen tools, or runnable as a CLI:
  python3 cpp_blob_emitter.py \\
      --input data.bin --output out.h \\
      --namespace foo [--symbol kFoo] [--include-guard FOO_H_] \\
      [--symbol-suffix Descriptor] [--gen-dir path/to/gen] [--compress]

If --symbol is omitted, it is derived from the basename of --output: the
substring before the first '.' is title-cased with underscores stripped, then
--symbol-suffix is appended (e.g. test_messages.descriptor.h with suffix
'Descriptor' produces TestMessagesDescriptor).

If --include-guard is omitted, it is derived from --output: when --gen-dir is
given the path is taken relative to it, and the result has separators/dots
replaced with underscores, is uppercased, and gets a trailing '_'.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import os
import re
import sys
import textwrap
import zlib

_HEADER_TEMPLATE = """/*
 * Copyright (C) 2020 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.
 */

#ifndef {include_guard}
#define {include_guard}

#include <stddef.h>
#include <stdint.h>
#include <array>

namespace {namespace} {{

inline constexpr std::array<uint8_t, {size}> k{symbol}{{
{binary}}};

}}  // namespace {namespace}

#endif  // {include_guard}
"""


def _format_byte_literal(data):
  # Match the historical output of gen_cc_proto_descriptor.py exactly so
  # consumers see byte-identical headers after the extraction.
  try:
    ord(data[0])
    ordinal = ord
  except TypeError:
    ordinal = lambda x: x
  binary = '{' + ', '.join('{0:#04x}'.format(ordinal(c)) for c in data) + '}'
  return textwrap.fill(
      binary, width=80, initial_indent='    ', subsequent_indent='     ')


def derive_symbol(output_path, suffix=''):
  """Title-case the part of basename(output_path) before the first '.'.

  e.g. 'test_messages.descriptor.h' with suffix 'Descriptor' →
  'TestMessagesDescriptor'.
  """
  base = os.path.basename(output_path).split('.', 1)[0]
  return base.title().replace('_', '') + suffix


def derive_include_guard(output_path, gen_dir=''):
  """Compute a C++ include guard token from output_path.

  When gen_dir is provided, the output is taken relative to it first. The
  resulting path has '/', '\\\\' and '.' replaced with '_', is uppercased,
  and gets a trailing '_'.
  """
  rel = os.path.relpath(output_path,
                        gen_dir) if gen_dir else os.path.basename(output_path)
  return re.sub(r'[^A-Z0-9_]', '_', rel.upper()) + '_'


def emit_array(data, output_path, *, symbol, namespace, include_guard):
  """Write `data` to `output_path` as a constexpr std::array<uint8_t, N>."""
  binary = _format_byte_literal(data)
  with open(output_path, 'wb') as f:
    f.write(
        _HEADER_TEMPLATE.format(
            include_guard=include_guard,
            namespace=namespace,
            symbol=symbol,
            size=len(data),
            binary=binary,
        ).encode())


def emit_compressed_array(data,
                          output_path,
                          *,
                          symbol,
                          namespace,
                          include_guard,
                          level=9):
  """Like emit_array, but zlib-compresses `data` first.

  Consumers must inflate the resulting array at runtime. The uncompressed
  size is not encoded — pass `level=zlib.Z_BEST_COMPRESSION` for max ratio
  (the default).
  """
  emit_array(
      zlib.compress(data, level),
      output_path,
      symbol=symbol,
      namespace=namespace,
      include_guard=include_guard)


def _main():
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('--output', required=True, help='Path to .h to emit.')
  parser.add_argument(
      '--namespace', required=True, help='C++ namespace for the array.')
  parser.add_argument(
      '--symbol',
      default=None,
      help='Array symbol name (sans leading "k"). '
      'Default: derived from --output.')
  parser.add_argument(
      '--symbol-suffix',
      default='',
      help='Suffix appended when --symbol is derived from --output.')
  parser.add_argument(
      '--include-guard',
      default=None,
      help='Include guard token. Default: derived from --output.')
  parser.add_argument(
      '--gen-dir',
      default='',
      help='Build gen dir; used to make --output relative when '
      'deriving --include-guard.')
  parser.add_argument(
      '--compress',
      action='store_true',
      help='zlib-compress the bytes before embedding.')
  parser.add_argument('input', help='Path to bytes file.')
  args = parser.parse_args()

  symbol = args.symbol if args.symbol is not None else derive_symbol(
      args.output, args.symbol_suffix)
  include_guard = (
      args.include_guard if args.include_guard is not None else
      derive_include_guard(args.output, args.gen_dir))

  with open(args.input, 'rb') as f:
    data = f.read()
  emit = emit_compressed_array if args.compress else emit_array
  emit(
      data,
      args.output,
      symbol=symbol,
      namespace=args.namespace,
      include_guard=include_guard)
  return 0


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