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

# Take a file where each line is a tab-separated list of arguments for DX (or
# D8) and create a self-contained directory with all the input files
# and a script which replays the same DX invocations as the original list.
#
# Usage:
#
#     create_dx_replay.py <dx-args-script> <output-dir>
#
# The <dx-args-script> is a text file where each line contains tab-separated
# arguments for a DX (D8) call.
# The script 'tools/test_android_cts.py' can log DX invocations during an AOSP
# build to such a file. Use 'test_android_cts.py --tool=d8 --d8log=<file> ...'.

from __future__ import print_function
from os.path import join, isdir, exists, basename
from os import rmdir
from shutil import copy2
import argparse
import os
import stat
import sys

import utils

IN_SUBDIR = 'in' # subdirectory for the local copy of the input files
OUT_SUBDIR = 'out' # subdirectory prefix for the output of DX
REPLAY_SCRIPT_NAME = 'replay_script.py'

# This function will be called with arguments of the original DX invocation. It
# copies the original input files into the local input directory and replaces
# the references in orig_args to the local input files.
# Returns the new line to be appended to the replay script.
def process_line(out_dir, input_counter, orig_args):
  args = []
  inputs = []
  for arg in orig_args:
    if arg.startswith('--output='):
      continue # nothing to do, just skip this arg
    if arg.startswith('--'):
      args.append(arg)
    else:
      # 'arg' is the path of an input file: copy arg to local dir with
      # a new, unique name
      if isdir(arg):
        raise IOError("Adding directories ('{}') to the replay script is not"
          " implemented.".format(arg))
      elif not exists(arg):
        print("The input file to DX does not exist: '{}'.".format(arg))

      input_file = '{}_{}'.format(input_counter, basename(arg))

      copy2(arg, join(out_dir, join(IN_SUBDIR, input_file)))
      inputs.append(input_file)

  return 'call_dx({}, {}, {})\n'.format(input_counter, args, inputs)


def parse_arguments():
  parser = argparse.ArgumentParser(
      description = 'Creates a self-contained directory for playing back a '
      ' sequence of DX calls.')
  parser.add_argument('dx_call_log',
      help = 'File containing tab-separated arguments for a DX call on each'
      ' line.')
  parser.add_argument('output_dir',
      help = 'Target path the create the self-contained directory at.')
  return parser.parse_args()

def Main():
  args = parse_arguments()

  if isdir(args.output_dir):
    rmdir(args.output_dir) # make sure to write only to empty out dir

  utils.makedirs_if_needed(join(args.output_dir, IN_SUBDIR))

  # create the first lines of the replay script
  replay_script = \
"""#!/usr/bin/env python
import os
import shutil
import subprocess
import sys

SCRIPT_DIR = os.path.abspath(os.path.normpath(os.path.join(__file__, '..')))
IN_SUBDIR = '{}'
OUT_SUBDIR = '{}'

def call_dx(input_counter, args, inputs):
  out_dir = os.path.join(SCRIPT_DIR, OUT_SUBDIR, str(input_counter))
  if not os.path.isdir(out_dir):
    os.makedirs(out_dir)
  full_inputs = [os.path.join(SCRIPT_DIR, IN_SUBDIR, i) for i in inputs]
  subprocess.check_call(sys.argv[1:] + args + ['--output=' + out_dir]
      + full_inputs)

if len(sys.argv) < 2:
  raise IOError('Usage: create_dx_replay.py <dx-command>'
      ' # can be multiple args')
abs_out_dir = os.path.join(SCRIPT_DIR, OUT_SUBDIR)
if os.path.isdir(abs_out_dir):
  shutil.rmtree(abs_out_dir)

""".format(IN_SUBDIR, OUT_SUBDIR)

  with open(args.dx_call_log) as f:
    lines = f.read().splitlines()

  input_counter = 1
  for line in lines:
    replay_script += \
        process_line(args.output_dir, input_counter, line.split('\t'))
    input_counter += 1

  script_file = join(args.output_dir, REPLAY_SCRIPT_NAME)
  with open(script_file, 'w') as f:
    f.write(replay_script)

  # chmod +x for script_file
  st = os.stat(script_file)
  os.chmod(script_file, st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)

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