#!/usr/bin/env python

import os, sys
from subprocess import Popen, PIPE, check_call, CalledProcessError

def tar_file(dir, no_compress=False):
    """
    Create tar file from ``dir``.  If ``no_compress`` is True, don't
    compress; otherwise, compress using bzip2.

    If on a Mac, set the environment variable ``COPYFILE_DISABLE`` to
    True and use the subprocess module to call tar (to use the new
    environment variable).  Otherwise, use the tarfile module to
    create the tar file.
    """
    if sys.platform == 'darwin':
        # workaround OS X issue -- see trac #2522
        COPYFILE_DISABLE = True
        os.environ['COPYFILE_DISABLE'] = 'true'
        if no_compress:
            cmd = "tar -cf %s.spkg %s" % (dir, dir)
        else:
            cmd = "tar -cf - %s | bzip2 > %s.spkg" % (dir, dir)
        try:
            check_call(cmd, shell=True)
        except CalledProcessError:
            print "Package creation failed."
            sys.exit(1)
    else:
        import tarfile
        if no_compress:
            mode = "w"
        else:
            mode = "w:bz2"
        try:
            tar = tarfile.open("%s.spkg" % dir, mode=mode)
            tar.add(dir, exclude=lambda f: f == ".DS_Store")
            tar.close()
        except tarfile.TarError:
            print "Package creation failed."
            sys.exit(1)

def main():
    import re
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-n", "--no-compress", "--no_compress", "--nocompress",
                      dest="no_compress", action="store_true",
                      help="don't compress the spkg file")
    (options, args) = parser.parse_args()
    for path in args:
        print "Creating {1}Sage package from {0}".format(path,
                "uncompressed " if options.no_compress else "")

        if not os.path.isdir(path):
            print "No directory %s" % path
            sys.exit(1)
        dir = os.path.basename(path.rstrip("/"))
        file = dir + ".spkg"
        s = dir.split("-", 1)
        try:
            name = s[0]
            version = s[1]
        except IndexError:
            name = dir
            version = ""

        if len(version) == 0:
            print "Warning: no version number detected"
        else:
            m = re.match(r"[0-9]+[-.0-9a-zA-Z]*(\.p[0-9]+)?$", version)
            if not m:
                print "Warning: version number (%s) not of the expected form." % version
                print """The version number should start with a number and contain only numbers,
letters, periods, and hyphens.  It may optionally end with a string of
the form 'pNUM' where NUM is a non-negative integer.

Proceeding anyway..."""

        tar_file(dir, no_compress = options.no_compress)

        size = os.path.getsize(file)
        if size < 1024 * 1024:
            size = "%sK" % (size / 1024)
        else:
            size = "%0.1fM" % (size / (1024 * 1024.0))

        if os.path.exists(os.path.join(dir, "SPKG.txt")):
            spkg_txt = "Good"
        else:
            spkg_txt = "File is missing"

        p = Popen("cd '%s' && hg diff" % dir, shell=True, stdout=PIPE, stderr=PIPE)
        std_out, std_err = p.communicate()
        if len(std_err) != 0:
            hgrepo_txt = "Error reading repository"
        elif len(std_out) != 0:
            hgrepo_txt = "Unchecked in changes"
        else:
            hgrepo_txt = "Good"

        print """
Created package %(file)s.

    NAME: %(name)s
 VERSION: %(version)s
    SIZE: %(size)s
 HG REPO: %(hgrepo)s
SPKG.txt: %(spkg)s

Please test this package using

   sage -f %(file)s

immediately.""" % {'file': file, 'name': name, 'version': version, 'size': size,
           'hgrepo': hgrepo_txt, 'spkg': spkg_txt},
        if options.no_compress:
            print ""
            print ""
        else:
            print """ Also, note that you can use

   sage -pkg_nc %(dir)s

to make an uncompressed version of the package (useful if the
package is full of compressed data).
""" % {'dir': dir}

if __name__ == "__main__":
    main()
