def configs = [
    [
        label: 'windows',
        versions: ['py27', 'py34', 'py35', 'py36'],
    ],
    [
        label: 'windows64',
        versions: ['py27', 'py34', 'py35', 'py36'],
    ],
    [
        label: 'sierra',
        versions: ['py27', 'py34', 'py35', 'py36'],
    ],
    [
        label: 'docker',
        imageName: 'quay.io/pypa/manylinux1_x86_64',
        versions: [
            'cp27-cp27m', 'cp27-cp27mu',
            'cp34-cp34m', 'cp35-cp35m', 'cp36-cp36m'
        ],
    ],
    [
        label: 'docker',
        imageName: 'quay.io/pypa/manylinux1_i686',
        versions: [
            'cp27-cp27m', 'cp27-cp27mu',
            'cp34-cp34m', 'cp35-cp35m', 'cp36-cp36m'
        ],
    ],
]


def build(version, label, imageName) {
    try {
        timeout(time: 30, unit: 'MINUTES') {
            if (label.contains("windows")) {
                def pythonPath = [
                    py27: "C:\\Python27\\python.exe",
                    py34: "C:\\Python34\\python.exe",
                    py35: "C:\\Python35\\python.exe",
                    py36: "C:\\Python36\\python.exe"
                ]
                if (version == "py35" || version == "py36") {
                    libIncludePaths = [
                        "windows": [
                            "lib": "C:\\libsodium-1.0.15-msvc\\Win32\\Release\\v140\\static"
                        ],
                        "windows64": [
                            "lib": "C:\\libsodium-1.0.15-msvc\\x64\\Release\\v140\\static"
                        ]
                    ]
                } else {
                    libIncludePaths = [
                        "windows": [
                            "lib": "C:\\libsodium-1.0.15-msvc\\Win32\\Release\\v100\\static"
                        ],
                        "windows64": [
                            "lib": "C:\\libsodium-1.0.15-msvc\\x64\\Release\\v100\\static"
                        ]
                    ]
                }
                bat """
                    wmic qfe
                    @set PATH="C:\\Python27";"C:\\Python27\\Scripts";%PATH%
                    @set PYTHON="${pythonPath[version]}"
                    @set PYNACL_SODIUM_LIBRARY_NAME=sodium
                    @set PYNACL_SODIUM_STATIC=1
                    @set SODIUM_INSTALL=system

                    @set INCLUDE="C:\\libsodium-1.0.15-msvc\\include";%INCLUDE%
                    @set LIB="${libIncludePaths[label]['lib']}";%LIB%
                    virtualenv -p %PYTHON% .release
                    call .release\\Scripts\\activate
                    pip install wheel virtualenv
                    pip wheel pynacl --wheel-dir=wheelhouse --no-binary pynacl
                    pip install -f wheelhouse pynacl --no-index
                    python -c "import nacl.signing; key = nacl.signing.SigningKey.generate(); signature = key.sign(b'test'); key.verify_key.verify(signature)"
                """
            } else if (label.contains("sierra")) {
                def pythonPath = [
                    py27: "/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7",
                    py34: "/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4",
                    py35: "/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5",
                    py36: "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6",
                ]
                ansiColor {
                    sh """#!/usr/bin/env bash
                        set -xe
                        # output the list of things we've installed as a point in time check of how up
                        # to date the builder is
                        /usr/sbin/system_profiler SPInstallHistoryDataType

                        # Jenkins logs in as a non-interactive shell, so we don't even have /usr/local/bin in PATH
                        export PATH="/usr/local/bin:\${PATH}"
                        export PATH="/Users/jenkins/.pyenv/shims:\${PATH}"

                        printenv

                        virtualenv .venv -p ${pythonPath[version]}
                        source .venv/bin/activate
                        pip install -U wheel # upgrade wheel to latest before we use it to build the wheel
                        pip wheel pynacl --wheel-dir=wheelhouse --no-binary pynacl
                        pip install -f wheelhouse pynacl --no-index
                        python -c "import nacl.signing; key = nacl.signing.SigningKey.generate(); signature = key.sign(b'test'); key.verify_key.verify(signature)"
                        lipo -info `find .venv -name '*.so'`
                    """
                }
            } else if (label.contains("docker")) {
                linux32 = ""
                if (imageName.contains("i686")) {
                    linux32 = "linux32"
                }
                sh """#!/usr/bin/env bash
                    set -x -e
                    # Because we are doing this as root in the container, but we write to a mounted dir that is outside the container
                    # we need to make sure we set these files writable such that the jenkins user can delete them afterwards
                    mkdir -p tmpwheelhouse
                    mkdir -p wheelhouse
                    chmod -R 777 tmpwheelhouse
                    chmod -R 777 wheelhouse

                    $linux32 /opt/python/$version/bin/pip install cffi six
                    $linux32 /opt/python/$version/bin/pip wheel --no-binary pynacl --no-deps pynacl -w tmpwheelhouse/
                    $linux32 auditwheel repair tmpwheelhouse/PyNaCl*.whl -w wheelhouse/
                    $linux32 /opt/python/$version/bin/pip install pynacl --no-index -f wheelhouse/
                    $linux32 /opt/python/$version/bin/python -c "import nacl.signing; key = nacl.signing.SigningKey.generate(); signature = key.sign(b'test'); key.verify_key.verify(signature)"
                """
            }
            archiveArtifacts artifacts: "**/wheelhouse/PyNaCl*.whl"
        }
    } finally {
        deleteDir()
    }

}

def builders = [:]
for (config in configs) {
    def label = config["label"]
    def versions = config["versions"]

    for (_version in versions) {
        def version = _version

        if (label.contains("docker")) {
            def imageName = config["imageName"]
            def combinedName = "${imageName}-${version}"
            builders[combinedName] = {
                node(label) {
                    stage(combinedName) {
                        def buildImage = docker.image(imageName)
                        buildImage.pull()
                        buildImage.inside("-u root") {
                            build(version, label, imageName)
                        }
                    }
                }
            }
        } else {
            def combinedName = "${label}-${version}"
            builders[combinedName] = {
                node(label) {
                    stage(combinedName) {
                        build(version, label, "")
                    }
                }
            }
        }
    }
}

parallel builders
