#!/usr/bin/env python3
# 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 argparse
import tempfile
import subprocess
import hashlib
from compat import iteritems

SOURCE_TARGET = [
    ('protos/perfetto/trace_processor/trace_processor.proto',
     'python/perfetto/trace_processor/trace_processor.descriptor'),
    ('protos/perfetto/metrics/metrics.proto',
     'python/perfetto/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(source, target):
  assert os.path.exists(os.path.join(ROOT_DIR, target)), \
      'Output file {} does not exist and so cannot be checked'.format(target)

  sha1_file = target + '.sha1'
  assert os.path.exists(sha1_file), \
      'SHA1 file {} does not exist and so cannot be checked'.format(sha1_file)

  with open(sha1_file, '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):
  # delete=False + manual unlink is required for Windows. Otherwise the temp
  # file is kept locked exclusively and unaccassible until it's destroyed.
  with tempfile.NamedTemporaryFile(delete=False) 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()
    fdescriptor.close()
    os.remove(fdescriptor.name)
    with open(target, 'wb') as out:
      out.write(s)

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