#!/usr/bin/env python3
# Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import os
import subprocess
import sys

try:
  from perfetto.trace_processor import TraceProcessor
except ImportError:
  sys.exit(
      'Unable to analyze perfetto trace without the perfetto library. '
      'Install instructions:\n'
      '    sudo apt install python3-pip\n'
      '    pip3 install perfetto')

def ensure_record_android_trace(tmp_dir):
  record_android_trace_path = os.path.join(tmp_dir, 'record_android_trace')
  if not os.path.exists(record_android_trace_path):
    cmd = [
        'curl',
        '--output',
        record_android_trace_path,
        '--silent',
        'https://raw.githubusercontent.com/google/perfetto/master/tools/'
            'record_android_trace'
    ]
    subprocess.check_call(cmd)
    assert os.path.exists(record_android_trace_path)
  return record_android_trace_path

def record_android_trace(out_dir, tmp_dir, device_id=None):
  record_android_trace_path = ensure_record_android_trace(tmp_dir)
  config_path = os.path.join(os.path.dirname(__file__), 'config.pbtx')
  perfetto_trace_path = os.path.join(out_dir, 'trace.perfetto-trace')
  cmd = [
      sys.executable,
      record_android_trace_path,
      '--config',
      config_path,
      '--out',
      perfetto_trace_path,
      '--no-open']
  if device_id is not None:
    cmd.extend(['--serial', device_id])
  perfetto_process = subprocess.Popen(
      cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  lines = []
  for line in perfetto_process.stdout:
    line = line.decode('utf-8')
    lines.append(line)
    if 'enabled ftrace' in line.strip():
      return perfetto_process, perfetto_trace_path
  raise ValueError(
      'Expected to find line containing: enabled ftrace, got: %s' % lines)

def stop_record_android_trace(perfetto_process, out_dir):
  if perfetto_process.poll() is not None:
    raise ValueError('Expected perfetto process to be running')
  # perfetto should terminate in at most 15 seconds, 
  perfetto_config_duration=15
  stdout, stderr = perfetto_process.communicate(
      timeout=perfetto_config_duration*2)
  stdout = stdout.decode('utf-8')
  stderr = stderr.decode('utf-8')
  assert perfetto_process.returncode == 0
  assert os.path.exists(os.path.join(out_dir, 'trace.perfetto-trace'))

# https://perfetto.dev/docs/analysis/sql-tables
def find_slices_by_name(slice_name, options, trace_processor):
  return trace_processor.query(
      'SELECT slice.dur, slice.ts FROM slice'
          ' INNER JOIN thread_track ON (slice.track_id = thread_track.id)'
          ' INNER JOIN thread using (utid)'
          ' INNER JOIN process using (upid)'
          ' WHERE slice.name = "%s"'
          ' AND process.name = "%s"'
          ' ORDER BY slice.ts ASC'
          % (slice_name, options.app_id))

def find_unique_slice_by_name(slice_name, options, trace_processor):
  query_it = find_slices_by_name(slice_name, options, trace_processor)
  assert len(query_it) == 1
  return next(query_it)

def get_slice_end_since_start(slice, initial_slice):
  return (slice.ts + slice.dur - initial_slice.ts) / 1000000
