"""tools for BuildApplet and BuildApplication"""

import warnings
warnings.warnpy3k("the buildtools module is deprecated and is removed in 3.0",
              stacklevel=2)

import sys
import os
import string
import imp
import marshal
from Carbon import Res
import Carbon.Files
import Carbon.File
import MacOS
import macostools
import macresource
try:
    import EasyDialogs
except ImportError:
    EasyDialogs = None
import shutil


BuildError = "BuildError"

# .pyc file (and 'PYC ' resource magic number)
MAGIC = imp.get_magic()

# Template file (searched on sys.path)
TEMPLATE = "PythonInterpreter"

# Specification of our resource
RESTYPE = 'PYC '
RESNAME = '__main__'

# A resource with this name sets the "owner" (creator) of the destination
# It should also have ID=0. Either of these alone is not enough.
OWNERNAME = "owner resource"

# Default applet creator code
DEFAULT_APPLET_CREATOR="Pyta"

# OpenResFile mode parameters
READ = 1
WRITE = 2

# Parameter for FSOpenResourceFile
RESOURCE_FORK_NAME=Carbon.File.FSGetResourceForkName()

def findtemplate(template=None):
    """Locate the applet template along sys.path"""
    if MacOS.runtimemodel == 'macho':
        return None
    if not template:
        template=TEMPLATE
    for p in sys.path:
        file = os.path.join(p, template)
        try:
            file, d1, d2 = Carbon.File.FSResolveAliasFile(file, 1)
            break
        except (Carbon.File.Error, ValueError):
            continue
    else:
        raise BuildError, "Template %r not found on sys.path" % (template,)
    file = file.as_pathname()
    return file

def process(template, filename, destname, copy_codefragment=0,
        rsrcname=None, others=[], raw=0, progress="default", destroot=""):

    if progress == "default":
        if EasyDialogs is None:
            print "Compiling %s"%(os.path.split(filename)[1],)
            process = None
        else:
            progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
            progress.label("Compiling...")
            progress.inc(0)
    # check for the script name being longer than 32 chars. This may trigger a bug
    # on OSX that can destroy your sourcefile.
    if '#' in os.path.split(filename)[1]:
        raise BuildError, "BuildApplet could destroy your sourcefile on OSX, please rename: %s" % filename
    # Read the source and compile it
    # (there's no point overwriting the destination if it has a syntax error)

    fp = open(filename, 'rU')
    text = fp.read()
    fp.close()
    try:
        code = compile(text + '\n', filename, "exec")
    except SyntaxError, arg:
        raise BuildError, "Syntax error in script %s: %s" % (filename, arg)
    except EOFError:
        raise BuildError, "End-of-file in script %s" % (filename,)

    # Set the destination file name. Note that basename
    # does contain the whole filepath, only a .py is stripped.

    if string.lower(filename[-3:]) == ".py":
        basename = filename[:-3]
        if MacOS.runtimemodel != 'macho' and not destname:
            destname = basename
    else:
        basename = filename

    if not destname:
        if MacOS.runtimemodel == 'macho':
            destname = basename + '.app'
        else:
            destname = basename + '.applet'
    if not rsrcname:
        rsrcname = basename + '.rsrc'

    # Try removing the output file. This fails in MachO, but it should
    # do any harm.
    try:
        os.remove(destname)
    except os.error:
        pass
    process_common(template, progress, code, rsrcname, destname, 0,
        copy_codefragment, raw, others, filename, destroot)


def update(template, filename, output):
    if MacOS.runtimemodel == 'macho':
        raise BuildError, "No updating yet for MachO applets"
    if progress:
        if EasyDialogs is None:
            print "Updating %s"%(os.path.split(filename)[1],)
            progress = None
        else:
            progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
    else:
        progress = None
    if not output:
        output = filename + ' (updated)'

    # Try removing the output file
    try:
        os.remove(output)
    except os.error:
        pass
    process_common(template, progress, None, filename, output, 1, 1)


def process_common(template, progress, code, rsrcname, destname, is_update,
        copy_codefragment, raw=0, others=[], filename=None, destroot=""):
    if MacOS.runtimemodel == 'macho':
        return process_common_macho(template, progress, code, rsrcname, destname,
            is_update, raw, others, filename, destroot)
    if others:
        raise BuildError, "Extra files only allowed for MachoPython applets"
    # Create FSSpecs for the various files
    template_fsr, d1, d2 = Carbon.File.FSResolveAliasFile(template, 1)
    template = template_fsr.as_pathname()

    # Copy data (not resources, yet) from the template
    if progress:
        progress.label("Copy data fork...")
        progress.set(10)

    if copy_codefragment:
        tmpl = open(template, "rb")
        dest = open(destname, "wb")
        data = tmpl.read()
        if data:
            dest.write(data)
        dest.close()
        tmpl.close()
        del dest
        del tmpl

    # Open the output resource fork

    if progress:
        progress.label("Copy resources...")
        progress.set(20)
    try:
        output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)
    except MacOS.Error:
        destdir, destfile = os.path.split(destname)
        Res.FSCreateResourceFile(destdir, unicode(destfile), RESOURCE_FORK_NAME)
        output = Res.FSOpenResourceFile(destname, RESOURCE_FORK_NAME, WRITE)

    # Copy the resources from the target specific resource template, if any
    typesfound, ownertype = [], None
    try:
        input = Res.FSOpenResourceFile(rsrcname, RESOURCE_FORK_NAME, READ)
    except (MacOS.Error, ValueError):
        pass
        if progress:
            progress.inc(50)
    else:
        if is_update:
            skip_oldfile = ['cfrg']
        else:
            skip_oldfile = []
        typesfound, ownertype = copyres(input, output, skip_oldfile, 0, progress)
        Res.CloseResFile(input)

    # Check which resource-types we should not copy from the template
    skiptypes = []
    if 'vers' in typesfound: skiptypes.append('vers')
    if 'SIZE' in typesfound: skiptypes.append('SIZE')
    if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4',
            'icl8', 'ics4', 'ics8', 'ICN#', 'ics#']
    if not copy_codefragment:
        skiptypes.append('cfrg')
##  skipowner = (ownertype != None)

    # Copy the resources from the template

    input = Res.FSOpenResourceFile(template, RESOURCE_FORK_NAME, READ)
    dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)

    Res.CloseResFile(input)
##  if ownertype is None:
##      raise BuildError, "No owner resource found in either resource file or template"
    # Make sure we're manipulating the output resource file now

    Res.UseResFile(output)

    if ownertype is None:
        # No owner resource in the template. We have skipped the
        # Python owner resource, so we have to add our own. The relevant
        # bundle stuff is already included in the interpret/applet template.
        newres = Res.Resource('\0')
        newres.AddResource(DEFAULT_APPLET_CREATOR, 0, "Owner resource")
        ownertype = DEFAULT_APPLET_CREATOR

    if code:
        # Delete any existing 'PYC ' resource named __main__

        try:
            res = Res.Get1NamedResource(RESTYPE, RESNAME)
            res.RemoveResource()
        except Res.Error:
            pass

        # Create the raw data for the resource from the code object
        if progress:
            progress.label("Write PYC resource...")
            progress.set(120)

        data = marshal.dumps(code)
        del code
        data = (MAGIC + '\0\0\0\0') + data

        # Create the resource and write it

        id = 0
        while id < 128:
            id = Res.Unique1ID(RESTYPE)
        res = Res.Resource(data)
        res.AddResource(RESTYPE, id, RESNAME)
        attrs = res.GetResAttrs()
        attrs = attrs | 0x04    # set preload
        res.SetResAttrs(attrs)
        res.WriteResource()
        res.ReleaseResource()

    # Close the output file

    Res.CloseResFile(output)

    # Now set the creator, type and bundle bit of the destination.
    # Done with FSSpec's, FSRef FInfo isn't good enough yet (2.3a1+)
    dest_fss = Carbon.File.FSSpec(destname)
    dest_finfo = dest_fss.FSpGetFInfo()
    dest_finfo.Creator = ownertype
    dest_finfo.Type = 'APPL'
    dest_finfo.Flags = dest_finfo.Flags | Carbon.Files.kHasBundle | Carbon.Files.kIsShared
    dest_finfo.Flags = dest_finfo.Flags & ~Carbon.Files.kHasBeenInited
    dest_fss.FSpSetFInfo(dest_finfo)

    macostools.touched(destname)
    if progress:
        progress.label("Done.")
        progress.inc(0)

def process_common_macho(template, progress, code, rsrcname, destname, is_update,
        raw=0, others=[], filename=None, destroot=""):
    # Check that we have a filename
    if filename is None:
        raise BuildError, "Need source filename on MacOSX"
    # First make sure the name ends in ".app"
    if destname[-4:] != '.app':
        destname = destname + '.app'
    # Now deduce the short name
    destdir, shortname = os.path.split(destname)
    if shortname[-4:] == '.app':
        # Strip the .app suffix
        shortname = shortname[:-4]
    # And deduce the .plist and .icns names
    plistname = None
    icnsname = None
    if rsrcname and rsrcname[-5:] == '.rsrc':
        tmp = rsrcname[:-5]
        plistname = tmp + '.plist'
        if os.path.exists(plistname):
            icnsname = tmp + '.icns'
            if not os.path.exists(icnsname):
                icnsname = None
        else:
            plistname = None
    if not icnsname:
        dft_icnsname = os.path.join(sys.prefix, 'Resources/Python.app/Contents/Resources/PythonApplet.icns')
        if os.path.exists(dft_icnsname):
            icnsname = dft_icnsname
    if not os.path.exists(rsrcname):
        rsrcname = None
    if progress:
        progress.label('Creating bundle...')
    import bundlebuilder
    builder = bundlebuilder.AppBuilder(verbosity=0)
    builder.mainprogram = filename
    builder.builddir = destdir
    builder.name = shortname
    builder.destroot = destroot
    if rsrcname:
        realrsrcname = macresource.resource_pathname(rsrcname)
        builder.files.append((realrsrcname,
            os.path.join('Contents/Resources', os.path.basename(rsrcname))))
    for o in others:
        if type(o) == str:
            builder.resources.append(o)
        else:
            builder.files.append(o)
    if plistname:
        import plistlib
        builder.plist = plistlib.Plist.fromFile(plistname)
    if icnsname:
        builder.iconfile = icnsname
    if not raw:
        builder.argv_emulation = 1
    builder.setup()
    builder.build()
    if progress:
        progress.label('Done.')
        progress.inc(0)

##  macostools.touched(dest_fss)

# Copy resources between two resource file descriptors.
# skip a resource named '__main__' or (if skipowner is set) with ID zero.
# Also skip resources with a type listed in skiptypes.
#
def copyres(input, output, skiptypes, skipowner, progress=None):
    ctor = None
    alltypes = []
    Res.UseResFile(input)
    ntypes = Res.Count1Types()
    progress_type_inc = 50/ntypes
    for itype in range(1, 1+ntypes):
        type = Res.Get1IndType(itype)
        if type in skiptypes:
            continue
        alltypes.append(type)
        nresources = Res.Count1Resources(type)
        progress_cur_inc = progress_type_inc/nresources
        for ires in range(1, 1+nresources):
            res = Res.Get1IndResource(type, ires)
            id, type, name = res.GetResInfo()
            lcname = string.lower(name)

            if lcname == OWNERNAME and id == 0:
                if skipowner:
                    continue # Skip this one
                else:
                    ctor = type
            size = res.size
            attrs = res.GetResAttrs()
            if progress:
                progress.label("Copy %s %d %s"%(type, id, name))
                progress.inc(progress_cur_inc)
            res.LoadResource()
            res.DetachResource()
            Res.UseResFile(output)
            try:
                res2 = Res.Get1Resource(type, id)
            except MacOS.Error:
                res2 = None
            if res2:
                if progress:
                    progress.label("Overwrite %s %d %s"%(type, id, name))
                    progress.inc(0)
                res2.RemoveResource()
            res.AddResource(type, id, name)
            res.WriteResource()
            attrs = attrs | res.GetResAttrs()
            res.SetResAttrs(attrs)
            Res.UseResFile(input)
    return alltypes, ctor

def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
    names = []
    if os.path.exists(dsttree):
        shutil.rmtree(dsttree)
    os.mkdir(dsttree)
    todo = os.listdir(srctree)
    while todo:
        this, todo = todo[0], todo[1:]
        if this in exceptlist:
            continue
        thispath = os.path.join(srctree, this)
        if os.path.isdir(thispath):
            thiscontent = os.listdir(thispath)
            for t in thiscontent:
                todo.append(os.path.join(this, t))
        names.append(this)
    for this in names:
        srcpath = os.path.join(srctree, this)
        dstpath = os.path.join(dsttree, this)
        if os.path.isdir(srcpath):
            os.mkdir(dstpath)
        elif os.path.islink(srcpath):
            endpoint = os.readlink(srcpath)
            os.symlink(endpoint, dstpath)
        else:
            if progress:
                progress.label('Copy '+this)
                progress.inc(0)
            shutil.copy2(srcpath, dstpath)

def writepycfile(codeobject, cfile):
    import marshal
    fc = open(cfile, 'wb')
    fc.write('\0\0\0\0') # MAGIC placeholder, written later
    fc.write('\0\0\0\0') # Timestap placeholder, not needed
    marshal.dump(codeobject, fc)
    fc.flush()
    fc.seek(0, 0)
    fc.write(MAGIC)
    fc.close()
