#!/usr/bin/env python
# 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.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import re
import sys
import argparse
import tempfile
import subprocess
import hashlib
import textwrap
from compat import iteritems

SOURCE_TARGET = {
    'protos/perfetto/config/perfetto_config.proto':
        'src/perfetto_cmd/perfetto_config.descriptor.h',
    'protos/perfetto/metrics/metrics.proto':
        'src/trace_processor/metrics/metrics.descriptor.h',
    'protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.proto':
        'src/trace_processor/importers/proto/chrome_compositor_scheduler_state.descriptor.h',
    'src/protozero/test/example_proto/test_messages.proto':
        'src/protozero/test/example_proto/test_messages.descriptor.h',
    'protos/perfetto/trace/track_event/track_event.proto':
        'src/trace_processor/importers/proto/track_event.descriptor.h',
    'protos/perfetto/metrics/custom_options.proto':
        'src/trace_processor/metrics/custom_options.descriptor.h',
}

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

SCRIPT_PATH = 'tools/gen_binary_descriptors'


def hash_path(path):
  hash = hashlib.sha1()
  with open(os.path.join(ROOT_DIR, path), 'rb') as f:
    hash.update(f.read())
  return hash.hexdigest()


def find_protoc():
  for root, _, files in os.walk(os.path.join(ROOT_DIR, 'out')):
    if 'protoc' in files:
      return os.path.join(root, 'protoc')
  return None


def check(source, target):
  assert os.path.exists(os.path.join(ROOT_DIR, target)), \
      'Output file {} does not exist and so cannot be checked'.format(target)

  with open(target, 'rb') as f:
    s = f.read()

  hashes = re.findall(r'// SHA1\((.*)\)\n// (.*)\n', s.decode())
  assert sorted([SCRIPT_PATH, source]) == sorted([key for key, _ in hashes])
  for path, expected_sha1 in hashes:
    actual_sha1 = hash_path(os.path.join(ROOT_DIR, path))
    assert actual_sha1 == expected_sha1, \
        'In {} hash given for {} did not match'.format(target, path)


def generate(source, target, protoc_path):
  _, source_name = os.path.split(source)
  _, target_name = os.path.split(target)
  assert source_name.replace('.proto', '.descriptor.h') == target_name

  with tempfile.NamedTemporaryFile() as fdescriptor:
    subprocess.check_call([
        protoc_path,
        '--include_imports',
        '--proto_path=.',
        '--proto_path=' + \
            os.path.join(ROOT_DIR, "buildtools", "protobuf", "src"),
        '--descriptor_set_out={}'.format(fdescriptor.name),
        source,
    ],
                          cwd=ROOT_DIR)

    s = fdescriptor.read()
    proto_name = source_name[:-len('.proto')].title().replace("_", "")
    constant_name = 'k' + proto_name + 'Descriptor'
    try:
      ord(s[0])
      ordinal = ord
    except TypeError:
      ordinal = lambda x: x
    binary = '{' + ', '.join('{0:#04x}'.format(ordinal(c)) for c in s) + '}'
    binary = textwrap.fill(
        binary, width=80, initial_indent='    ', subsequent_indent='     ')
    include_guard = target.replace('/', '_').replace('.', '_').upper() + '_'

    with open(os.path.join(ROOT_DIR, target), 'wb') as f:
      f.write("""/*
 * 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.
 */

#ifndef {include_guard}
#define {include_guard}

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

#include <array>

// This file was autogenerated by tools/gen_binary_descriptors. Do not edit.

// SHA1({script_path})
// {script_hash}
// SHA1({source_path})
// {source_hash}

// This is the proto {proto_name} encoded as a ProtoFileDescriptor to allow
// for reflection without libprotobuf full/non-lite protos.

namespace perfetto {{

constexpr std::array<uint8_t, {size}> {constant_name}{{
{binary}}};

}}  // namespace perfetto

#endif  // {include_guard}
""".format(
          proto_name=proto_name,
          size=len(s),
          constant_name=constant_name,
          binary=binary,
          include_guard=include_guard,
          script_path=SCRIPT_PATH,
          script_hash=hash_path(__file__),
          source_path=source,
          source_hash=hash_path(os.path.join(source)),
      ).encode())


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

  try:
    for source, target in iteritems(SOURCE_TARGET):
      if args.check_only:
        check(source, target)
      else:
        protoc = args.protoc or find_protoc()
        assert protoc, 'protoc not found specific (--protoc PROTOC_PATH)'
        assert os.path.exists(protoc), '{} does not exist'.format(protoc)
        if protoc is not args.protoc:
          print('Using protoc: {}'.format(protoc))
        generate(source, target, protoc)
  except AssertionError as e:
    if not str(e):
      raise
    print('Error: {}'.format(e))
    return 1


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