#!/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'
    ),
    (
      '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/chrome/all_chrome_metrics.proto',
      'src/trace_processor/metrics/chrome/all_chrome_metrics.descriptor.h'
    ),
    (
      'protos/perfetto/trace_processor/trace_processor.proto',
      'src/trace_processor/python/trace_processor/trace_processor.descriptor'
    ),
    (
      'protos/perfetto/metrics/metrics.proto',
      'src/trace_processor/python/trace_processor/metrics.descriptor'
    ),
]

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_using_shas(source, target, file_with_shas):
  with open(file_with_shas, '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 check_raw_descriptor(source, target):
  sha1_file = target + '.sha1'
  assert os.path.exists(sha1_file), \
      'SHA1 file {} does not exist and so cannot be checked'.format(sha1_file)

  check_using_shas(source, target, sha1_file)


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)

  if target.endswith('.descriptor.h'):
    check_using_shas(source, target, target)
  elif target.endswith('.descriptor'):
    check_raw_descriptor(source, target)


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

  proto_name = source_name[:-len('.proto')].title().replace("_", "")
  try:
    ord(descriptor_bytes[0])
    ordinal = ord
  except TypeError:
    ordinal = lambda x: x
  binary = '{' + ', '.join('{0:#04x}'
    .format(ordinal(c)) for c in descriptor_bytes) + '}'
  binary = textwrap.fill(
      binary, width=80, initial_indent='    ', subsequent_indent='     ')

  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}> k{proto_name}Descriptor{{
{binary}}};

}}  // namespace perfetto

#endif  // {include_guard}
""".format(
        proto_name=proto_name,
        size=len(descriptor_bytes),
        binary=binary,
        include_guard=target.replace('/', '_').replace('.', '_').upper() + '_',
        script_path=SCRIPT_PATH,
        script_hash=hash_path(__file__),
        source_path=source,
        source_hash=hash_path(os.path.join(source)),
    ).encode())


def write_raw_descriptor(source, target, descriptor_bytes):
  with open(target, 'wb') as out:
    out.write(descriptor_bytes)

  sha1_path = target + '.sha1'
  with open(sha1_path, 'wb') as c:
    c.write("""
// SHA1({script_path})
// {script_hash}
// SHA1({source_path})
// {source_hash}
""".format(
        script_path=SCRIPT_PATH,
        script_hash=hash_path(__file__),
        source_path=source,
        source_hash=hash_path(os.path.join(source)),
    ).encode())



def generate(source, target, protoc_path):
  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()
    if target.endswith('.descriptor.h'):
      write_cpp_header(source, target, s)
    elif target.endswith('.descriptor'):
      write_raw_descriptor(source, target, s)
    else:
      raise Exception('Unsupported target extension for file {}'.format(target))

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 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())
