# Script for building the _ssl module for Windows.
# Uses Perl to setup the OpenSSL environment correctly
# and build OpenSSL, then invokes a simple nmake session
# for _ssl.pyd itself.

# THEORETICALLY, you can:
# * Unpack the latest SSL release one level above your main Python source
#   directory.  It is likely you will already find the zlib library and
#   any other external packages there.
# * Install ActivePerl and ensure it is somewhere on your path.
# * Run this script from the PCBuild directory.
#
# it should configure and build SSL, then build the ssl Python extension
# without intervention.

import os, sys, re

# Find all "foo.exe" files on the PATH.
def find_all_on_path(filename, extras = None):
    entries = os.environ["PATH"].split(os.pathsep)
    ret = []
    for p in entries:
        fname = os.path.abspath(os.path.join(p, filename))
        if os.path.isfile(fname) and fname not in ret:
            ret.append(fname)
    if extras:
        for p in extras:
            fname = os.path.abspath(os.path.join(p, filename))
            if os.path.isfile(fname) and fname not in ret:
                ret.append(fname)
    return ret

# Find a suitable Perl installation for OpenSSL.
# cygwin perl does *not* work.  ActivePerl does.
# Being a Perl dummy, the simplest way I can check is if the "Win32" package
# is available.
def find_working_perl(perls):
    for perl in perls:
        fh = os.popen(perl + ' -e "use Win32;"')
        fh.read()
        rc = fh.close()
        if rc:
            continue
        return perl
    print "Can not find a suitable PERL:"
    if perls:
        print " the following perl interpreters were found:"
        for p in perls:
            print " ", p
        print " None of these versions appear suitable for building OpenSSL"
    else:
        print " NO perl interpreters were found on this machine at all!"
    print " Please install ActivePerl and ensure it appears on your path"
    print "The Python SSL module was not built"
    return None

# Locate the best SSL directory given a few roots to look into.
def find_best_ssl_dir(sources):
    candidates = []
    for s in sources:
        try:
            s = os.path.abspath(s)
            fnames = os.listdir(s)
        except os.error:
            fnames = []
        for fname in fnames:
            fqn = os.path.join(s, fname)
            if os.path.isdir(fqn) and fname.startswith("openssl-"):
                candidates.append(fqn)
    # Now we have all the candidates, locate the best.
    best_parts = []
    best_name = None
    for c in candidates:
        parts = re.split("[.-]", os.path.basename(c))[1:]
        # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
        if len(parts) >= 4:
            continue
        if parts > best_parts:
            best_parts = parts
            best_name = c
    if best_name is not None:
        print "Found an SSL directory at '%s'" % (best_name,)
    else:
        print "Could not find an SSL directory in '%s'" % (sources,)
    return best_name

def main():
    debug = "-d" in sys.argv
    build_all = "-a" in sys.argv
    make_flags = ""
    if build_all:
        make_flags = "-a"
    # perl should be on the path, but we also look in "\perl" and "c:\\perl"
    # as "well known" locations
    perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
    perl = find_working_perl(perls)
    if perl is None:
        sys.exit(1)

    print "Found a working perl at '%s'" % (perl,)
    # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
    ssl_dir = find_best_ssl_dir(("../..",))
    if ssl_dir is None:
        sys.exit(1)

    old_cd = os.getcwd()
    try:
        os.chdir(ssl_dir)
        # If the ssl makefiles do not exist, we invoke Perl to generate them.
        if not os.path.isfile(os.path.join(ssl_dir, "32.mak")) or \
           not os.path.isfile(os.path.join(ssl_dir, "d32.mak")):
            print "Creating the makefiles..."
            # Put our working Perl at the front of our path
            os.environ["PATH"] = os.path.split(perl)[0] + \
                                          os.pathsep + \
                                          os.environ["PATH"]
            # ms\32all.bat will reconfigure OpenSSL and then try to build
            # all outputs (debug/nondebug/dll/lib).  So we filter the file
            # to exclude any "nmake" commands and then execute.
            tempname = "ms\\32all_py.bat"
            
            in_bat  = open("ms\\32all.bat")
            temp_bat = open(tempname,"w")
            while 1:
                cmd = in_bat.readline()
                print 'cmd', repr(cmd)
                if not cmd: break
                if cmd.strip()[:5].lower() == "nmake":
                    continue
                temp_bat.write(cmd)
            in_bat.close()
            temp_bat.close()
            os.system(tempname)
            try:
                os.remove(tempname)
            except:
                pass

        # Now run make.
        print "Executing nmake over the ssl makefiles..."
        if debug:
            rc = os.system("nmake /nologo -f d32.mak")
            if rc:
                print "Executing d32.mak failed"
                print rc
                sys.exit(rc)
        else:
            rc = os.system("nmake /nologo -f 32.mak")
            if rc:
                print "Executing 32.mak failed"
                print rc
                sys.exit(rc)
    finally:
        os.chdir(old_cd)
    # And finally, we can build the _ssl module itself for Python.
    defs = "SSL_DIR=%s" % (ssl_dir,)
    if debug:
        defs = defs + " " + "DEBUG=1"
    rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags)
    sys.exit(rc)

if __name__=='__main__':
    main()
