#!/usr/bin/env python
# Copyright (c) 2019, 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.

# Convenience script for running run_on_app.py finding minimum memory need for
# compiling a given app back in time. This utilizes the prebuilt r8 jars on
# cloud storage.
# The script find all commits that exists on cloud storage in the given range.
# It will then run the oldest and newest such commit, and gradually fill in
# the commits in between.

import optparse
import os
import subprocess
import sys
import utils

MASTER_COMMITS = 'gs://r8-releases/raw/master'
APPS = ['gmscore', 'nest', 'youtube', 'gmail', 'chrome']
COMPILERS = ['d8', 'r8']

def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option('--compiler',
                    help='The compiler to use',
                    default='d8',
                    choices=COMPILERS)
  result.add_option('--app',
                    help='What app to run on',
                    default='gmail',
                    choices=APPS)
  result.add_option('--top',
                    default=utils.get_HEAD_sha1(),
                    help='The most recent commit to test')
  result.add_option('--bottom',
                    help='The oldest commit to test')
  result.add_option('--output',
                    default='build',
                    help='Directory where to output results')
  result.add_option('--timeout',
                    type=int,
                    default=0,
                    help='Set timeout instead of waiting for OOM.')
  return result.parse_args(argv)


class GitCommit(object):
  def __init__(self, git_hash, destination_dir, destination, timestamp):
    self.git_hash = git_hash
    self.destination_dir = destination_dir
    self.destination = destination
    self.timestamp = timestamp

  def __str__(self):
    return '%s : %s (%s)' % (self.git_hash, self.destination, self.timestamp)

  def __repr__(self):
    return self.__str__()

def git_commit_from_hash(hash):
  commit_timestamp = subprocess.check_output(['git', 'show', '--no-patch',
                                         '--no-notes', '--pretty=\'%ct\'',
                                         hash]).strip().strip('\'')
  destination_dir = '%s/%s/' % (MASTER_COMMITS, hash)
  destination = '%s%s' % (destination_dir, 'r8.jar')
  commit = GitCommit(hash, destination_dir, destination, commit_timestamp)
  return commit

def enumerate_git_commits(options):
  top = options.top if options.top else utils.get_HEAD_sha1()
  # TODO(ricow): if not set, search back 1000
  if not options.bottom:
    raise Exception('No bottom specified')
  bottom = options.bottom
  output = subprocess.check_output(['git', 'rev-list', '--first-parent', top])
  found_bottom = False
  commits = []
  for c in output.splitlines():
    commits.append(git_commit_from_hash(c.strip()))
    if c.strip() == bottom:
      found_bottom = True
      break
  if not found_bottom:
    raise Exception('Bottom not found, did you not use a merge commit')
  return commits

def get_available_commits(commits):
  cloud_commits = subprocess.check_output(['gsutil.py', 'ls', MASTER_COMMITS]).splitlines()
  available_commits = []
  for commit in commits:
    if commit.destination_dir in cloud_commits:
      available_commits.append(commit)
  return available_commits

def print_commits(commits):
  for commit in commits:
    print(commit)

def permutate_range(start, end):
  diff = end - start
  assert diff >= 0
  if diff == 1:
    return [start, end]
  if diff == 0:
    return [start]
  half = end - (diff / 2)
  numbers = [half]
  first_half = permutate_range(start, half - 1)
  second_half = permutate_range(half + 1, end)
  for index in range(len(first_half)):
    numbers.append(first_half[index])
    if index < len(second_half):
      numbers.append(second_half[index])
  return numbers

def permutate(number_of_commits):
  assert number_of_commits > 0
  numbers = permutate_range(0, number_of_commits - 1)
  assert all(n in numbers for n in range(number_of_commits))
  return numbers

def pull_r8_from_cloud(commit):
  utils.download_file_from_cloud_storage(commit.destination, utils.R8_JAR)

def run_on_app(options, commit):
  app = options.app
  compiler = options.compiler
  cmd = ['tools/run_on_app.py',
         '--app', app,
         '--compiler', compiler,
         '--timeout', str(options.timeout),
         '--no-build', '--find-min-xmx']
  stdout = subprocess.check_output(cmd)
  output_path = options.output or 'build'
  time_commit = '%s_%s' % (commit.timestamp, commit.git_hash)
  time_commit_path = os.path.join(output_path, time_commit)
  if not os.path.exists(time_commit_path):
    os.makedirs(time_commit_path)
  stdout_path = os.path.join(time_commit_path, 'stdout')
  with open(stdout_path, 'w') as f:
    f.write(stdout)
  print('Wrote stdout to: %s' % stdout_path)


def benchmark(commits, options):
  commit_permutations = permutate(len(commits))
  count = 0
  for index in commit_permutations:
    count += 1
    print('Running commit %s out of %s' % (count, len(commits)))
    commit = commits[index]
    if not utils.cloud_storage_exists(commit.destination):
      # We may have a directory, but no r8.jar
      continue
    pull_r8_from_cloud(commit)
    print('Running for commit: %s' % commit.git_hash)
    run_on_app(options, commit)

def main(argv):
  (options, args) = ParseOptions(argv)
  if not options.app:
     raise Exception('Please specify an app')
  commits = enumerate_git_commits(options)
  available_commits = get_available_commits(commits)
  print('Running for:')
  print_commits(available_commits)
  benchmark(available_commits, options)

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
