#!/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 Exception 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))
