#!/usr/bin/env python3
# Copyright (C) 2022 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 sys
import logging
import re
import subprocess

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

AMALGAMATION_MAP = {
    'python/tools/record_android_trace.py':
        'tools/record_android_trace',
    'python/tools/tracebox.py':
        'tools/tracebox',
    'python/tools/traceconv.py':
        'tools/traceconv',
    'python/tools/trace_processor.py':
        'tools/trace_processor',
    'python/tools/cpu_profile.py':
        'tools/cpu_profile',
    'python/tools/heap_profile.py':
        'tools/heap_profile',
    'python/tools/install_test_reporter_app.py':
        'tools/install_test_reporter_app',
}


def amalgamate_file(fname, stack=None, done=None, in_progress=None):
  stack = [] if stack is None else stack
  done = set() if done is None else done
  in_progress = set() if in_progress is None else in_progress
  if fname in in_progress:
    cycle = ' > '.join(stack + [fname])
    logging.fatal('Cycle detected in %s', cycle)
    sys.exit(1)
  if fname in done:
    return []
  logging.debug('Processing %s', fname)
  done.add(fname)
  in_progress.add(fname)
  with open(fname, encoding='utf-8') as f:
    lines = f.readlines()
  outlines = []
  for line in lines:
    if line.startswith('from perfetto') or line.startswith('import perfetto'):
      if not re.match(r'from perfetto[.][.\w]+\s+import\s+[*]$', line):
        logging.fatal('Error in %s on line \"%s\"', fname, line.rstrip())
        logging.fatal('Only "from perfetto.foo import *" is supported in '
                      'sources that are used in //tools and get amalgamated')
        sys.exit(1)
      pkg = line.split()[1]
      fpath = os.path.join('python', pkg.replace('.', os.sep) + '.py')
      outlines.append('\n# ----- Amalgamator: begin of %s\n' % fpath)
      outlines += amalgamate_file(fpath, stack + [fname], done, in_progress)
      outlines.append('\n# ----- Amalgamator: end of %s\n' % fpath)
    elif '__file__' in line and not 'amalgamator:nocheck' in line:
      logging.fatal(
          '__file__ is not allowed in sources that get amalgamated.'
          'In %s on line \"%s\"', fname, line.rstrip())
      sys.exit(1)

    else:
      outlines.append(line)
  in_progress.remove(fname)
  logging.debug('%s: %d lines', fname, len(outlines))
  return outlines


def amalgamate(src, dst, check_only=False):
  lines = amalgamate_file(src)
  banner = '''
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# DO NOT EDIT. Auto-generated by %s
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
'''
  lines.insert(lines.index('\n'), banner % os.path.relpath(__file__, ROOT_DIR))
  new_content = ''.join(lines)
  yapf = os.path.join(ROOT_DIR, '.venv',
                      'bin' if sys.platform != 'win32' else 'Scripts', 'yapf')
  new_content = subprocess.check_output([yapf], text=True, input=new_content)

  if check_only:
    if not os.path.exists(dst):
      return False
    with open(dst, encoding='utf-8') as f:
      return f.read() == new_content

  logging.info('Amalgamating %s -> %s', src, dst)
  with open(dst + '.tmp', 'w', encoding='utf-8') as f:
    f.write(new_content)
  os.chmod(dst + '.tmp', 0o755)
  os.replace(dst + '.tmp', dst)
  return True


def main():
  check_only = '--check-only' in sys.argv
  logging.basicConfig(
      format='%(levelname)-8s: %(message)s',
      level=logging.DEBUG if '-v' in sys.argv else logging.INFO)
  os.chdir(ROOT_DIR)  # Make the execution cwd-independent.
  success = True
  for src, dst in AMALGAMATION_MAP.items():
    success = success and amalgamate(src, dst, check_only)
  return 0 if success else 1


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