#!/usr/bin/env python3
# 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 python3
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())
