#!/usr/bin/python
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file is based on build/copy_test_data_ios.py
"""Copies data files or directories into a given output directory.

Since the output of this script is intended to be use by GYP, all resulting
paths are using Unix-style forward flashes.
"""

import argparse
import os
import posixpath
import shutil
import sys
if os.name == 'nt':
  import win32api

# The name of an environment variable that when set to |'1'|, signals to us
# that we should log all output directories that we have staged a copy to to
# our stderr output. This output could then, for example, be captured and
# analyzed by an external tool that is interested in these directories.
_ShouldLogEnvKey = 'STARBOARD_GYP_SHOULD_LOG_COPIES'


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 = posixpath.join(path, item)
    output.extend(ListFilesForPath(full_path))
  return output


def CalcInputs(inputs):
  """Computes the full list of input files. The output is a list of
  (filepath, filepath relative to input dir)"""
  # |inputs| is a list of paths, which may be directories.
  output = []
  for input_file in inputs:
    file_list = ListFilesForPath(input_file)
    dirname = posixpath.dirname(input_file)
    output.extend([(x, posixpath.relpath(x, dirname)) for x in file_list])
  return output


def CopyFiles(files_to_copy, output_basedir):
  """Copies files to the given output directory."""
  for (filename, relative_filename) in files_to_copy:
    if os.name == 'nt':
      # Some of the files (especially for layout tests) result in very long
      # paths (especially on build machines) such that shutil.copy fails.
      filename = win32api.GetShortPathName(filename)
      output_basedir = win32api.GetShortPathName(output_basedir)

    # In certain cases, files would fail to open on windows if relative paths
    # were provided.  Using absolute paths fixes this.
    filename = os.path.abspath(filename)
    output_basedir = os.path.abspath(output_basedir)
    output_filename = os.path.abspath(os.path.join(output_basedir,
                                                   relative_filename))
    output_dir = os.path.dirname(output_filename)

    # 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(filename, output_filename)


def DoMain(argv):
  """Called by GYP using pymod_do_main."""
  parser = argparse.ArgumentParser()
  parser.add_argument('-o', dest='output_dir', help='output directory')
  parser.add_argument(
      '--inputs',
      action='store_true',
      dest='list_inputs',
      help='prints a list of all input files')
  parser.add_argument(
      '--outputs',
      action='store_true',
      dest='list_outputs',
      help='prints a list of all output files')
  parser.add_argument(
      'input_paths',
      metavar='path',
      nargs='+',
      help='path to an input file or directory')
  options = parser.parse_args(argv)

  if os.environ.get(_ShouldLogEnvKey, None) == '1':
    if options.output_dir is not None:
      print >> sys.stderr, 'COPY_LOG:', options.output_dir

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

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

  if options.list_outputs:
    outputs = [posixpath.join(options.output_dir, x[1]) for x in files_to_copy]
    return '\n'.join(outputs)

  CopyFiles(files_to_copy, options.output_dir)
  return


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


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