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

# 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 and _hashlib
# Python extensions 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:
            # note: do not abspath s; the build will fail if any
            # higher up directory name has spaces in it.
            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,)
    sys.stdout.flush()
    return best_name

def run_configure(configure, do_script):
    os.system("perl Configure "+configure)
    os.system(do_script)

def main():
    build_all = "-a" in sys.argv
    if sys.argv[1] == "Release":
        arch = "x86"
        debug = False
        configure = "VC-WIN32"
        do_script = "ms\\do_masm"
        makefile = "ms\\nt.mak"
    elif sys.argv[1] == "Debug":
        arch = "x86"
        debug = True
        configure = "VC-WIN32"
        do_script = "ms\\do_masm"
        makefile="ms\\d32.mak"
    elif sys.argv[1] == "ReleaseItanium":
        arch = "ia64"
        debug = False
        configure = "VC-WIN64I"
        do_script = "ms\\do_win64i"
        makefile = "ms\\nt.mak"
        os.environ["VSEXTCOMP_USECL"] = "MS_ITANIUM"
    elif sys.argv[1] == "ReleaseAMD64":
        arch="amd64"
        debug=False
        configure = "VC-WIN64A"
        do_script = "ms\\do_win64a"
        makefile = "ms\\nt.mak"
        os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
    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,)
    sys.stdout.flush()
    # 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.
        # Due to a bug in this script, the makefile sometimes ended up empty
        # Force a regeneration if it is.
        if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
            print "Creating the makefiles..."
            sys.stdout.flush()
            # Put our working Perl at the front of our path
            os.environ["PATH"] = os.path.dirname(perl) + \
                                          os.pathsep + \
                                          os.environ["PATH"]
            run_configure(configure, do_script)
            if arch=="x86" and debug:
                # the do_masm script in openssl doesn't generate a debug
                # build makefile so we generate it here:
                os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)

        # Now run make.
        makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
        print "Executing ssl makefiles:", makeCommand
        sys.stdout.flush()
        rc = os.system(makeCommand)
        if rc:
            print "Executing "+makefile+" 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"
    makeCommand = 'nmake /nologo -f _ssl.mak ' + defs + " " + make_flags
    print "Executing:", makeCommand
    sys.stdout.flush()
    rc = os.system(makeCommand)
    sys.exit(rc)

if __name__=='__main__':
    main()
