#!/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 argparse
import filecmp
import os
import pathlib
import shutil
import subprocess
import sys
import tempfile

SOURCE_FILES = [
  {
    'files': [
      'protos/perfetto/common/builtin_clock.proto',
      'protos/perfetto/common/data_source_descriptor.proto',
      'protos/perfetto/config/data_source_config.proto',
      'protos/perfetto/config/trace_config.proto',
      'protos/perfetto/config/track_event/track_event_config.proto',
      'protos/perfetto/trace/interned_data/interned_data.proto',
      'protos/perfetto/trace/test_event.proto',
      'protos/perfetto/trace/trace.proto',
      'protos/perfetto/trace/trace_packet.proto',
      'protos/perfetto/trace/track_event/counter_descriptor.proto',
      'protos/perfetto/trace/track_event/debug_annotation.proto',
      'protos/perfetto/trace/track_event/track_descriptor.proto',
      'protos/perfetto/trace/track_event/track_event.proto',
    ],
    'guard_strip_prefix': 'PROTOS_PERFETTO_',
    'guard_add_prefix':'INCLUDE_PERFETTO_PUBLIC_PROTOS_',
    'path_strip_prefix': 'protos/perfetto',
    'path_add_prefix': 'perfetto/public/protos',
    'include_prefix': 'include/',
  },
  {
    'files': [
      'src/protozero/test/example_proto/library.proto',
      'src/protozero/test/example_proto/library_internals/galaxies.proto',
      'src/protozero/test/example_proto/test_messages.proto',
      'src/protozero/test/example_proto/upper_import.proto',
    ],
    'guard_strip_prefix': 'SRC_PROTOZERO_TEST_EXAMPLE_PROTO_',
    'guard_add_prefix':'SRC_SHARED_LIB_TEST_PROTOS_',
    'path_strip_prefix': 'src/protozero/test/example_proto',
    'path_add_prefix': 'src/shared_lib/test/protos',
  },
]

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
IS_WIN = sys.platform.startswith('win')

SCRIPT_PATH = 'tools/gen_c_protos'


def protozero_c_plugin_path(out_directory):
  path = os.path.join(out_directory,
                      'protozero_c_plugin') + ('.exe' if IS_WIN else '')
  assert os.path.isfile(path)
  return path


def protoc_path(out_directory):
  path = os.path.join(out_directory, 'protoc') + ('.exe' if IS_WIN else '')
  assert os.path.isfile(path)
  return path


def call(cmd, *args):
  path = os.path.join('tools', cmd)
  command = ['python3', path] + list(args)
  print('Running', ' '.join(command))
  try:
    subprocess.check_call(command, cwd=ROOT_DIR)
  except subprocess.CalledProcessError as e:
    assert False, 'Command: {} failed'.format(' '.join(command))


# Reformats filename
def clang_format(filename):
  path = os.path.join(ROOT_DIR, 'third_party', 'clang-format',
                      'clang-format') + ('.exe' if IS_WIN else '')
  assert os.path.isfile(
      path), "clang-format not found. Run tools/install-build-deps"
  subprocess.check_call([
      path, '--style=file:{}'.format(os.path.join(ROOT_DIR, '.clang-format')),
      '-i', filename
  ],
                        cwd=ROOT_DIR)


# Transforms filename extension like the ProtoZero C plugin
def transform_extension(filename):
  old_suffix = ".proto"
  new_suffix = ".pzc.h"
  if filename.endswith(old_suffix):
    return filename[:-len(old_suffix)] + new_suffix
  return filename


def generate(source, outdir, protoc_path, protozero_c_plugin_path, guard_strip_prefix, guard_add_prefix, path_strip_prefix, path_add_prefix):
  options = {
      'guard_strip_prefix': guard_strip_prefix,
      'guard_add_prefix': guard_add_prefix,
      'path_strip_prefix': path_strip_prefix,
      'path_add_prefix': path_add_prefix,
      'invoker': SCRIPT_PATH,
  }
  serialized_options = ','.join(
      ['{}={}'.format(name, value) for name, value in options.items()])
  subprocess.check_call([
      protoc_path,
      '--proto_path=.',
      '--plugin=protoc-gen-plugin={}'.format(protozero_c_plugin_path),
      '--plugin_out={}:{}'.format(serialized_options, outdir),
      source,
  ],
                        cwd=ROOT_DIR)


# Given filename, the path of a header generated by the ProtoZero C plugin,
# returns the path where the header should go in the public include directory.
# Example
#
# include_path_for("protos/perfetto/trace/trace.pzc.h") ==
# "include/perfetto/public/protos/trace/trace.pzc.h"
def include_path_for(filename):
  return os.path.join('include', 'perfetto', 'public', 'protos',
                      *pathlib.Path(transform_extension(filename)).parts[2:])


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--check-only', action='store_true')
  parser.add_argument('OUT')
  args = parser.parse_args()
  out = args.OUT

  call('ninja', '-C', out, 'protoc', 'protozero_c_plugin')

  try:
    with tempfile.TemporaryDirectory() as tmpdirname:
      for sources in SOURCE_FILES:
        for source in sources['files']:
          generate(source, tmpdirname, protoc_path(out), protozero_c_plugin_path(out),
                   guard_strip_prefix=sources['guard_strip_prefix'],
                   guard_add_prefix=sources['guard_add_prefix'],
                   path_strip_prefix=sources['path_strip_prefix'],
                   path_add_prefix=sources['path_add_prefix'],
                   )

          tmpfilename = os.path.join(tmpdirname, transform_extension(source))
          clang_format(tmpfilename)
          if source.startswith(sources['path_strip_prefix']):
            targetfilename = source[len(sources['path_strip_prefix']):]
          else:
            targetfilename = source

          targetfilename = sources['path_add_prefix'] + targetfilename

          if 'include_prefix' in sources:
            targetfilename = os.path.join(sources['include_prefix'], targetfilename)
          targetfilename = transform_extension(targetfilename)

          if args.check_only:
            if not filecmp.cmp(tmpfilename, targetfilename):
              raise AssertionError('Target {} does not match', targetfilename)
          else:
            os.makedirs(os.path.dirname(targetfilename), exist_ok=True)
            shutil.copyfile(tmpfilename, targetfilename)

  except AssertionError as e:
    if not str(e):
      raise
    print('Error: {}'.format(e))
    return 1


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