"""macostools - Various utility functions for MacOS.

mkalias(src, dst) - Create a finder alias 'dst' pointing to 'src'
copy(src, dst) - Full copy of 'src' to 'dst'
"""

from warnings import warnpy3k
warnpy3k("In 3.x, the macostools module is removed.", stacklevel=2)

from Carbon import Res
from Carbon import File, Files
import os
import errno
import MacOS
try:
    openrf = MacOS.openrf
except AttributeError:
    # Backward compatibility
    openrf = open

Error = 'macostools.Error'

BUFSIZ=0x80000      # Copy in 0.5Mb chunks

COPY_FLAGS = (Files.kIsStationary|Files.kNameLocked|Files.kHasBundle|
              Files.kIsInvisible|Files.kIsAlias)

#
# Not guaranteed to be correct or stay correct (Apple doesn't tell you
# how to do this), but it seems to work.
#
def mkalias(src, dst, relative=None):
    """Create a finder alias"""
    srcfsr = File.FSRef(src)
    # The next line will fail under unix-Python if the destination
    # doesn't exist yet. We should change this code to be fsref-based.
    dstdir, dstname = os.path.split(dst)
    if not dstdir: dstdir = os.curdir
    dstdirfsr = File.FSRef(dstdir)
    if relative:
        relativefsr = File.FSRef(relative)
        # ik mag er geen None in stoppen :-(
        alias = File.FSNewAlias(relativefsr, srcfsr)
    else:
        alias = srcfsr.FSNewAliasMinimal()

    dstfsr, dstfss = Res.FSCreateResourceFile(dstdirfsr, unicode(dstname),
        File.FSGetResourceForkName())
    h = Res.FSOpenResourceFile(dstfsr, File.FSGetResourceForkName(), 3)
    resource = Res.Resource(alias.data)
    resource.AddResource('alis', 0, '')
    Res.CloseResFile(h)

    dstfinfo = dstfss.FSpGetFInfo()
    dstfinfo.Flags = dstfinfo.Flags|0x8000    # Alias flag
    dstfss.FSpSetFInfo(dstfinfo)

def mkdirs(dst):
    """Make directories leading to 'dst' if they don't exist yet"""
    if dst == '' or os.path.exists(dst):
        return
    head, tail = os.path.split(dst)
    if os.sep == ':' and not ':' in head:
        head = head + ':'
    mkdirs(head)

    try:
        os.mkdir(dst, 0777)
    except OSError, e:
        # be happy if someone already created the path
        if e.errno != errno.EEXIST:
            raise


def touched(dst):
    """Tell the finder a file has changed. No-op on MacOSX."""
    import warnings
    warnings.warn("macostools.touched() has been deprecated",
                    DeprecationWarning, 2)

def touched_ae(dst):
    """Tell the finder a file has changed"""
    pardir = os.path.split(dst)[0]
    if not pardir:
        pardir = os.curdir
    import Finder
    f = Finder.Finder()
    f.update(File.FSRef(pardir))

def copy(src, dst, createpath=0, copydates=1, forcetype=None):
    """Copy a file, including finder info, resource fork, etc"""
    src = File.pathname(src)
    dst = File.pathname(dst)
    if createpath:
        mkdirs(os.path.split(dst)[0])

    ifp = open(src, 'rb')
    ofp = open(dst, 'wb')
    d = ifp.read(BUFSIZ)
    while d:
        ofp.write(d)
        d = ifp.read(BUFSIZ)
    ifp.close()
    ofp.close()

    ifp = openrf(src, '*rb')
    ofp = openrf(dst, '*wb')
    d = ifp.read(BUFSIZ)
    while d:
        ofp.write(d)
        d = ifp.read(BUFSIZ)
    ifp.close()
    ofp.close()

    srcfss = File.FSSpec(src)
    dstfss = File.FSSpec(dst)
    sf = srcfss.FSpGetFInfo()
    df = dstfss.FSpGetFInfo()
    df.Creator, df.Type = sf.Creator, sf.Type
    if forcetype is not None:
        df.Type = forcetype
    df.Flags = (sf.Flags & COPY_FLAGS)
    dstfss.FSpSetFInfo(df)
    if copydates:
        srcfsr = File.FSRef(src)
        dstfsr = File.FSRef(dst)
        catinfo, _, _, _ = srcfsr.FSGetCatalogInfo(Files.kFSCatInfoAllDates)
        dstfsr.FSSetCatalogInfo(Files.kFSCatInfoAllDates, catinfo)

def copytree(src, dst, copydates=1):
    """Copy a complete file tree to a new destination"""
    if os.path.isdir(src):
        mkdirs(dst)
        files = os.listdir(src)
        for f in files:
            copytree(os.path.join(src, f), os.path.join(dst, f), copydates)
    else:
        copy(src, dst, 1, copydates)
