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

import argparse
import gn_helpers
import os
import re
import shutil
import sys

def ParseArgs(args):
  args = args[1:]
  parser = argparse.ArgumentParser(
      description='A script to copy a file tree somewhere')

  parser.add_argument('--exclude_patterns', '-e',
      type=str,
      help='Patterns to exclude [passed to shutil.copytree]')
  parser.add_argument('--from', '-f',
      dest="copy_from",
      type=str,
      help='Source directory')
  parser.add_argument('--gn', '-g',
      dest='gn',
      default=False,
      action='store_true',
      help='Output for GN for multiple sources, but do not copy anything.')
  parser.add_argument('gn_paths',
      metavar='name path ignore_pattern',
      type=str,
      nargs='*',
      default=None,
      help='When --gn is given, the specification of source paths to list.')
  parser.add_argument('--to', '-t',
      type=str,
      help='Destination directory')

  return parser.parse_args(args)


def ValidateArgs(args):
  if args.gn:
    if args.exclude_patterns or args.copy_from or args.to:
      print "--gn mode does not accept other switches"
      return False
    if not args.gn_paths:
      print "--gn mode requires a list of source specifications"
      return False
    return True
  if not args.copy_from or not os.path.isdir(args.copy_from):
    print "--from argument must refer to a directory"
    return False
  if not args.to:
    print "--to is required"
    return False
  return True


def CopyTree(src, dst, ignore=None):
  names = os.listdir(src)
  if ignore is not None:
    ignored_names = ignore(src, names)
  else:
    ignored_names = set()

  if not os.path.exists(dst):
    os.makedirs(dst)
  errors = []
  for name in names:
    if name in ignored_names:
      continue
    srcname = os.path.join(src, name)
    dstname = os.path.join(dst, name)
    try:
      if os.path.isdir(srcname):
        CopyTree(srcname, dstname, ignore)
      else:
        shutil.copy(srcname, dstname)
    except (IOError, os.error) as why:
      errors.append((srcname, dstname, str(why)))
    # catch the Error from the recursive CopyTree so that we can
    # continue with other files
    except Error as err:
      errors.extend(err.args[0])
  try:
    shutil.copystat(src, dst)
  except WindowsError:
    # can't copy file access times on Windows
    pass
  except OSError as why:
    errors.extend((src, dst, str(why)))
  if errors:
    raise Error(errors)


def ListTree(src, ignore=None):
  names = os.listdir(src)
  if ignore is not None:
    ignored_names = ignore(src, names)
  else:
    ignored_names = set()

  srcnames = []
  for name in names:
    if name in ignored_names:
      continue
    srcname = os.path.join(src, name)
    if os.path.isdir(srcname):
      srcnames.extend(ListTree(srcname, ignore))
    else:
      srcnames.append(srcname)
  return srcnames


# source_dirs is organized such that sources_dirs[n] is the path for the source
# directory, and source_dirs[n+1] is a list of ignore patterns.
def SourcesToGN(source_dirs):
  if len(source_dirs) % 2 != 0:
    print "--gn list length should be a multiple of 2."
    return False
  data = []
  for i in xrange(0, len(source_dirs), 2):
    path = source_dirs[i]
    ignores = source_dirs[i + 1]
    if ignores in ["{}"]:
      sources = ListTree(path)
    else:
      patterns = ignores.split(',')
      sources = ListTree(path, ignore=shutil.ignore_patterns(*patterns))
    data.append(sources)
  scope_data = {"sources": data}
  print gn_helpers.ToGNString(scope_data)
  return True


def Main(argv):
  args = ParseArgs(argv)
  if not ValidateArgs(args):
    return -1

  if args.gn:
    SourcesToGN(args.gn_paths)
    return 0

  if args.exclude_patterns == None:
    CopyTree(args.copy_from, args.to)
  else:
    patterns = args.exclude_patterns.split(',')
    CopyTree(args.copy_from, args.to, ignore=shutil.ignore_patterns(*patterns))
  return 0


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