#!/usr/bin/env python3
# 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 a command over builds back in time. This
# utilizes the prebuilt full 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 time
import utils

MASTER_COMMITS = 'gs://r8-releases/raw/master'

def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option(
    '--cmd',
    help='Command to run')
  result.add_option(
    '--top',
    default=top_or_default(),
    help='The most recent commit to test')
  result.add_option(
    '--bottom',
    help='The oldest commit to test')
  result.add_option(
    '--dry-run',
    help='Do not download or run the command, but print the actions',
    default=False,
    action='store_true')
  result.add_option(
    '--output',
    default='build',
    help='Directory where to output results')
  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(top, bottom):
  output = subprocess.check_output(['git', 'rev-list', '--first-parent', top])
  found_bottom = False
  commits = []
  for c in output.splitlines():
    commit_hash = c.strip()
    commits.append(git_commit_from_hash(commit_hash))
    if commit_hash == 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 benchmark(commits, command, dryrun=False):
  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
    if not dryrun:
      pull_r8_from_cloud(commit)
    print('Running for commit: %s' % commit.git_hash)
    command(commit)

def top_or_default(top=None):
  return top if top else utils.get_HEAD_sha1()

def bottom_or_default(bottom=None):
  # TODO(ricow): if not set, search back 1000
  if not bottom:
    raise Exception('No bottom specified')
  return bottom

def run(command, top, bottom, dryrun=False):
  commits = enumerate_git_commits(top, bottom)
  available_commits = get_available_commits(commits)
  print('Running for:')
  print_commits(available_commits)
  benchmark(available_commits, command, dryrun=dryrun)

def make_cmd(options):
  return lambda commit: run_cmd(options, commit)

def run_cmd(options, commit):
  cmd = [options.cmd, commit.git_hash]
  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)
  print ' '.join(cmd)
  if not options.dry_run:
    if not os.path.exists(time_commit_path):
      os.makedirs(time_commit_path)
    stdout_path = os.path.join(time_commit_path, 'stdout')
    stderr_path = os.path.join(time_commit_path, 'stderr')
    with open(stdout_path, 'w') as stdout:
      with open(stderr_path, 'w') as stderr:
        process = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
        timeout = 1000
        while process.poll() is None and timeout > 0:
          time.sleep(1)
          timeout -= 1
        if process.poll() is None:
          process.kill()
          print "Task timed out"
          stderr.write("timeout\n")
  print('Wrote outputs to: %s' % time_commit_path)

def main(argv):
  (options, args) = ParseOptions(argv)
  if not options.cmd:
     raise Exception('Please specify a command')
  top = top_or_default(options.top)
  bottom = bottom_or_default(options.bottom)
  command = make_cmd(options)
  run(command, top, bottom, dryrun=options.dry_run)

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