#!/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.

import os
import argparse
import tempfile
import subprocess
import shutil

SOURCE_TARGET = [('protos/perfetto/trace/perfetto_trace.proto',
                  'python/perfetto')]

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

SCRIPT_PATH = 'tools/gen_python_protos'


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 generate(source: str, target: str, protoc_path, check_only):
  # delete=False + manual unlink is required for Windows. Otherwise the temp
  # file is kept locked exclusively and unaccassible until it's destroyed.
  with tempfile.TemporaryDirectory() as directory:
    subprocess.check_call([
        protoc_path,
        '--python_out={}'.format(directory),
        '--pyi_out={}'.format(directory),
        source,
    ],
                          cwd=ROOT_DIR)

    py_path = source.replace('.proto', '_pb2.py')
    pyi_path = source.replace('.proto', '_pb2.pyi')
    with open(os.path.join(directory, py_path), 'rb') as f:
      py = f.read()
    with open(os.path.join(directory, pyi_path), 'rb') as f:
      pyi = f.read()
    shutil.rmtree(directory)

    if check_only:
      with open(os.path.join(target, py_path), 'rb') as f:
        old_py = f.read()
      with open(os.path.join(target, pyi_path), 'rb') as f:
        old_pyi = f.read()
      if (old_py != py):
        raise AssertionError('Target {} does not match', py_path)
      if (old_pyi != pyi):
        raise AssertionError('Target {} does not match', pyi_path)
      return

    with open(os.path.join(target, py_path), 'wb') as out:
      out.write(py)

    with open(os.path.join(target, pyi_path), 'wb') as out:
      out.write(pyi)


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:
      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, args.check_only)
  except AssertionError as e:
    if not str(e):
      raise
    print('Error: {}'.format(e))
    return 1


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