#!/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())
