#!/usr/bin/python
# Copyright 2014 The Cobalt Authors. 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))
