#
# Establish standard library in database
#
import db
import os
import glob
import sys
import marshal
import optparse

conn = db.conn()
curs = conn.cursor()

VER = sys.hexversion

def importpy(path, modname, package):
    #print "Importing module", modname, "from", path
    src = file(path).read()
    curs.execute("""select count(*) from module where modName = %s""", (modname,))
    if curs.fetchone()[0] != 0:
        tp = "module"
        if package: tp = "package"
        raise ValueError("Cannot load %s %s: already in database" % (tp, modname))
    # Compile should be guarded by try/except
    c = compile(src, path, "exec")
    curs.execute("""insert into module
                            (modName, modPyVersion, modSource, modCode, modPackage, modFilePath, modCompileTime)
                            values (%s, %s, %s, %s, %s, %s, now())""", (modname, VER, src, marshal.dumps(c), package, path))
    conn.commit()

def importpkg(f, modlist):
    #print "importing package", f, modlist
    if os.path.isdir(f):
        # Subdirectories that are not packages should raise an error
        fn = os.path.join(f, "__init__.py")
        if os.path.exists(fn):
            importpy(fn, ".".join(modlist), 1)
            #print "Package __init__ imported"
            for ff in glob.glob(os.path.join(f, "*")):
                last = os.path.split(ff)[1]
                if os.path.isdir(ff):
                    ml = modlist + [last]
                    #print "--- subpackage", ff, ml
                    importpkg(ff, ml)
                elif ff.endswith('.py') and '.' not in last[:-3] and ff != "__init__.py":
                    importpy(os.path.join(path, ff), ".".join(modlist+[last[:-3]]), 0)
                else:
                    #print "Ignoring file", ff
                    pass
        else:
            # raise ImportError, "Package directory %s has no __init__.py" % f
            pass # assume non-package directories are data
    else:
        raise ImportError, "Package import from non-directory %s" % f
    #print "=== imported", f, modlist
    
        
def importdir(f, modlist):
    #print "importing directory", f, modlist
    if os.path.isdir(f):
        # Subdirectories that are not packages need to be ignored?
        fn = os.path.join(f, "__init__.py")
        #print "Looking for", fn
        if not os.path.exists(fn):
            for f in glob.glob(os.path.join(path, "*")):
                if os.path.isdir(f):
                    if os.path.exists(os.path.join(f, "__init__.py")):
                        importpkg(f, modlist + [os.path.split(f)[1]])
                    else:
                        pass # UNLESS IMPORTING SUBDIRECTORIES
                else:
                    flast = os.path.split(f)[1]
                    if f.endswith('.py') and '.' not in flast[:-3] and f != "__init__.py":
                        ml = modlist + [flast[:-3]]
                        importpy(os.path.join(path, f), ".".join(ml), 0)
        else:
            raise ImportError, "Directory %s appears to be a package" % f
    else:
        raise ImportError, "Non-directory argument %s to importdir" % f

if __name__ == "__main__":

    usage = "usage: %prog [options] arg ..."
    parser = optparse.OptionParser(usage=usage)
    parser.add_option("-d", "--delete", action="store_true", dest="delete", help="delete all existing modules")
    parser.add_option("-p", "--package", action="store_true", dest="package", default=False, help="directory arguments are packages")
    options, args = parser.parse_args()
    
    #print options; print args; sys.exit("Testing stopped")

    if options.delete:
        curs.execute("delete from module where modPyVersion=%s", (VER, ))
        print "All existing modules cleared"

    if options.package:
        styp = "package"
    else:
        styp = "directory"

    for path in args:
        last = os.path.split(path)[1]
        if os.path.isdir(path):
            if path[-1] in "\\/":
                path = path[:-1]
            if options.package:
                importpkg(path, [])
            else:
                importdir(path, [])
        elif last.endswith('.py') and '.' not in last[:-3] and last != "__init__.py":
            importpy(path, last[:-3], 0)
        else:
            print "Cannot import %s: not %s or Python source" % (path, styp)
