#!/usr/bin/env python
"""Copy files to a directory and ensure destination directory automatically.

If you want to copy files to a directory name, make sure to end it with a slash.
Otherwise its meaning will be interpreted as a regular filename, even if there
are multiple source files to copy.
"""
__author__ = 'Martin Blais <blais@furius.ca>'

import argparse
import collections
import os
import shutil
import sys
from os import path


def main():
    parser = argparse.ArgumentParser(description=__doc__.strip())
    parser.add_argument('sources', nargs='+', action='store')
    parser.add_argument('dest', action='store')
    args = parser.parse_args()

    sources = args.sources
    dest = args.dest

    # If there is more than a single source file to copy, make sure the
    # destination is specified a directory with a trailing slash.
    dest_isdir = dest.endswith(os.sep)
    if len(sources) > 1 and not dest_isdir:
        parser.error('Destination for multiple files must be directory (ends with slash)')

    jobs = []
    if dest_isdir:
        # If the destination is a directory, make a job to copy all the source files into it.
        for src in sources:
            jobs.append((src, path.join(dest, path.basename(src))))
    else:
        # If the destination is a file, make a job to copy to the file itself.
        for src in sources:
            jobs.append((src, dest))

    # Check the uniqueness of destination filenames.
    counts = collections.defaultdict(int)
    for _, dest in jobs:
        counts[dest] += 1
    if len(counts) != len(jobs):
        parser.error("Error: Collision in destination filenames: {}".format(
            key for (key, count) in counts if count > 1))

    # Process all the copy jobs.
    for src, dest in jobs:
        parent = path.dirname(dest)
        if not path.exists(parent):
            print >> sys.stderr, "Warning: Creating directory %s" % parent
            os.makedirs(parent)
        shutil.copyfile(src, dest)


if __name__ == '__main__':
    main()
