"""distutils.file_util

Utility functions for operating on single files."""

# created 2000/04/03, Greg Ward (extracted from util.py)

__revision__ = "$Id$"

import os
from distutils.errors import DistutilsFileError


# for generating verbose output in 'copy_file()'
_copy_action = { None:   'copying',
                 'hard': 'hard linking',
                 'sym':  'symbolically linking' }


def _copy_file_contents (src, dst, buffer_size=16*1024):
    """Copy the file 'src' to 'dst'; both must be filenames.  Any error
       opening either file, reading from 'src', or writing to 'dst',
       raises DistutilsFileError.  Data is read/written in chunks of
       'buffer_size' bytes (default 16k).  No attempt is made to handle
       anything apart from regular files."""

    # Stolen from shutil module in the standard library, but with
    # custom error-handling added.

    fsrc = None
    fdst = None
    try:
        try:
            fsrc = open(src, 'rb')
        except os.error, (errno, errstr):
            raise DistutilsFileError, \
                  "could not open '%s': %s" % (src, errstr)
        
        try:
            fdst = open(dst, 'wb')
        except os.error, (errno, errstr):
            raise DistutilsFileError, \
                  "could not create '%s': %s" % (dst, errstr)
        
        while 1:
            try:
                buf = fsrc.read (buffer_size)
            except os.error, (errno, errstr):
                raise DistutilsFileError, \
                      "could not read from '%s': %s" % (src, errstr)
            
            if not buf:
                break

            try:
                fdst.write(buf)
            except os.error, (errno, errstr):
                raise DistutilsFileError, \
                      "could not write to '%s': %s" % (dst, errstr)
            
    finally:
        if fdst:
            fdst.close()
        if fsrc:
            fsrc.close()

# _copy_file_contents()


def copy_file (src, dst,
               preserve_mode=1,
               preserve_times=1,
               update=0,
               link=None,
               verbose=0,
               dry_run=0):

    """Copy a file 'src' to 'dst'.  If 'dst' is a directory, then 'src'
       is copied there with the same name; otherwise, it must be a
       filename.  (If the file exists, it will be ruthlessly clobbered.)
       If 'preserve_mode' is true (the default), the file's mode (type
       and permission bits, or whatever is analogous on the current
       platform) is copied.  If 'preserve_times' is true (the default),
       the last-modified and last-access times are copied as well.  If
       'update' is true, 'src' will only be copied if 'dst' does not
       exist, or if 'dst' does exist but is older than 'src'.  If
       'verbose' is true, then a one-line summary of the copy will be
       printed to stdout.

       'link' allows you to make hard links (os.link) or symbolic links
       (os.symlink) instead of copying: set it to "hard" or "sym"; if it
       is None (the default), files are copied.  Don't set 'link' on
       systems that don't support it: 'copy_file()' doesn't check if
       hard or symbolic linking is available.

       Under Mac OS, uses the native file copy function in macostools;
       on other systems, uses '_copy_file_contents()' to copy file
       contents.

       Return true if the file was copied (or would have been copied),
       false otherwise (ie. 'update' was true and the destination is
       up-to-date)."""

    # XXX if the destination file already exists, we clobber it if
    # copying, but blow up if linking.  Hmmm.  And I don't know what
    # macostools.copyfile() does.  Should definitely be consistent, and
    # should probably blow up if destination exists and we would be
    # changing it (ie. it's not already a hard/soft link to src OR
    # (not update) and (src newer than dst).

    from stat import *
    from distutils.dep_util import newer

    if not os.path.isfile (src):
        raise DistutilsFileError, \
              "can't copy '%s': doesn't exist or not a regular file" % src

    if os.path.isdir (dst):
        dir = dst
        dst = os.path.join (dst, os.path.basename (src))
    else:
        dir = os.path.dirname (dst)

    if update and not newer (src, dst):
        if verbose:
            print "not copying %s (output up-to-date)" % src
        return 0

    try:
        action = _copy_action[link]
    except KeyError:
        raise ValueError, \
              "invalid value '%s' for 'link' argument" % link
    if verbose:
        if os.path.basename(dst) == os.path.basename(src):
            print "%s %s -> %s" % (action, src, dir)
        else:
            print "%s %s -> %s" % (action, src, dst)
            
    if dry_run:
        return 1

    # On a Mac, use the native file copy routine
    if os.name == 'mac':
        import macostools
        try:
            macostools.copy (src, dst, 0, preserve_times)
        except os.error, exc:
            raise DistutilsFileError, \
                  "could not copy '%s' to '%s': %s" % (src, dst, exc[-1])
    
    # If linking (hard or symbolic), use the appropriate system call
    # (Unix only, of course, but that's the caller's responsibility)
    elif link == 'hard':
        if not (os.path.exists (dst) and os.path.samefile (src, dst)):
            os.link (src, dst)
    elif link == 'sym':
        if not (os.path.exists (dst) and os.path.samefile (src, dst)):
            os.symlink (src, dst)

    # Otherwise (non-Mac, not linking), copy the file contents and
    # (optionally) copy the times and mode.
    else:
        _copy_file_contents (src, dst)
        if preserve_mode or preserve_times:
            st = os.stat (src)

            # According to David Ascher <da@ski.org>, utime() should be done
            # before chmod() (at least under NT).
            if preserve_times:
                os.utime (dst, (st[ST_ATIME], st[ST_MTIME]))
            if preserve_mode:
                os.chmod (dst, S_IMODE (st[ST_MODE]))

    return 1

# copy_file ()


# XXX I suspect this is Unix-specific -- need porting help!
def move_file (src, dst,
               verbose=0,
               dry_run=0):

    """Move a file 'src' to 'dst'.  If 'dst' is a directory, the file
       will be moved into it with the same name; otherwise, 'src' is
       just renamed to 'dst'.  Return the new full name of the file.

       Handles cross-device moves on Unix using
       'copy_file()'.  What about other systems???"""

    from os.path import exists, isfile, isdir, basename, dirname

    if verbose:
        print "moving %s -> %s" % (src, dst)

    if dry_run:
        return dst

    if not isfile (src):
        raise DistutilsFileError, \
              "can't move '%s': not a regular file" % src

    if isdir (dst):
        dst = os.path.join (dst, basename (src))
    elif exists (dst):
        raise DistutilsFileError, \
              "can't move '%s': destination '%s' already exists" % \
              (src, dst)

    if not isdir (dirname (dst)):
        raise DistutilsFileError, \
              "can't move '%s': destination '%s' not a valid path" % \
              (src, dst)

    copy_it = 0
    try:
        os.rename (src, dst)
    except os.error, (num, msg):
        if num == errno.EXDEV:
            copy_it = 1
        else:
            raise DistutilsFileError, \
                  "couldn't move '%s' to '%s': %s" % (src, dst, msg)

    if copy_it:
        copy_file (src, dst)
        try:
            os.unlink (src)
        except os.error, (num, msg):
            try:
                os.unlink (dst)
            except os.error:
                pass
            raise DistutilsFileError, \
                  ("couldn't move '%s' to '%s' by copy/delete: " + 
                   "delete '%s' failed: %s") % \
                  (src, dst, src, msg)

    return dst

# move_file ()


def write_file (filename, contents):
    """Create a file with the specified name and write 'contents' (a
       sequence of strings without line terminators) to it."""

    f = open (filename, "w")
    for line in contents:
        f.write (line + "\n")
    f.close ()
