#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Copies test data files or directories into a given output directory."""

from __future__ import print_function

import optparse
import os
import shutil
import sys

class WrongNumberOfArgumentsException(Exception):
  pass

def EscapePath(path):
  """Returns a path with spaces escaped."""
  return path.replace(" ", "\\ ")

def ListFilesForPath(path):
  """Returns a list of all the files under a given path."""
  output = []
  # Ignore revision control metadata directories.
  if (os.path.basename(path).startswith('.git') or
      os.path.basename(path).startswith('.svn')):
    return output

  # Files get returned without modification.
  if not os.path.isdir(path):
    output.append(path)
    return output

  # Directories get recursively expanded.
  contents = os.listdir(path)
  for item in contents:
    full_path = os.path.join(path, item)
    output.extend(ListFilesForPath(full_path))
  return output

def CalcInputs(inputs):
  """Computes the full list of input files for a set of command-line arguments.
  """
  # |inputs| is a list of paths, which may be directories.
  output = []
  for input in inputs:
    output.extend(ListFilesForPath(input))
  return output

def CopyFiles(relative_filenames, output_basedir):
  """Copies files to the given output directory."""
  for file in relative_filenames:
    relative_dirname = os.path.dirname(file)
    output_dir = os.path.join(output_basedir, relative_dirname)
    output_filename = os.path.join(output_basedir, file)

    # In cases where a directory has turned into a file or vice versa, delete it
    # before copying it below.
    if os.path.exists(output_dir) and not os.path.isdir(output_dir):
      os.remove(output_dir)
    if os.path.exists(output_filename) and os.path.isdir(output_filename):
      shutil.rmtree(output_filename)

    if not os.path.exists(output_dir):
      os.makedirs(output_dir)
    shutil.copy(file, output_filename)

def DoMain(argv):
  parser = optparse.OptionParser()
  usage = 'Usage: %prog -o <output_dir> [--inputs] [--outputs] <input_files>'
  parser.set_usage(usage)
  parser.add_option('-o', dest='output_dir')
  parser.add_option('--inputs', action='store_true', dest='list_inputs')
  parser.add_option('--outputs', action='store_true', dest='list_outputs')
  options, arglist = parser.parse_args(argv)

  if len(arglist) == 0:
    raise WrongNumberOfArgumentsException('<input_files> required.')

  files_to_copy = CalcInputs(arglist)
  escaped_files = [EscapePath(x) for x in CalcInputs(arglist)]
  if options.list_inputs:
    return '\n'.join(escaped_files)

  if not options.output_dir:
    raise WrongNumberOfArgumentsException('-o required.')

  if options.list_outputs:
    outputs = [os.path.join(options.output_dir, x) for x in escaped_files]
    return '\n'.join(outputs)

  CopyFiles(files_to_copy, options.output_dir)
  return

def main(argv):
  try:
    result = DoMain(argv[1:])
  except WrongNumberOfArgumentsException as e:
    print(e, file=sys.stderr)
    return 1
  if result:
    print(result)
  return 0

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