#!/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',
}

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=.',
        '--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())
