#!/usr/bin/env python3.7
"""
Collect distribution archives on a number of macOS
systems
"""
import concurrent.futures
import fnmatch
import os
import shutil
import socket
import subprocess
import sys
import time

VMs=["mojave.local", "highsierra.local"]

def is_up(vm):
    try:
        socket.gethostbyname(vm)
    except socket.error:
        return False

    return True

def validate_vms():
    not_up = []
    for vm in VMs:
        if not is_up(vm):
            not_up.append(vm)

    if not_up:
        print(f"Not all VMs are up: {', '.join(not_up)}")
        sys.exit(1)

def on_vm(vm, command):
    subprocess.check_call(["ssh", vm, "sh", "-lc", f"'source .profile; {command}'" ])

def vm_output(vm, command):
    return subprocess.check_output(["ssh", vm, "sh", "-lc", f"'source .profile; {command}'"])

def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)

def main():
    start_time = time.time()
    validate_vms()

    if os.path.exists("distribution-dir"):
        shutil.rmtree("distribution-dir")

    os.mkdir("distribution-dir")

    for vm in VMs:
        on_vm(vm, "cd Projects/pyobjc && ~/bin/hg pull -u")
        status = vm_output(vm, "cd Projects/pyobjc && ~/bin/hg status")
        if status:
            print(f"Mercurial status on {vm} is not empty")
            print(status)
            sys.exit(1)

        on_vm(vm, "cd Projects/pyobjc && rm -rf distribution-dir")

    # Start actually building in parallel to speed this up.
    futures = {}
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        for vm in VMs:
            fut = executor.submit(on_vm, vm, "cd Projects/pyobjc && development-support/collect-dist-archives")
            futures[fut] = vm

        for fut in concurrent.futures.as_completed(futures):
            try:
                data = fut.result()
            except Exception as exc:
                print(f'{futures[fut]} generated an exception: {exc}')
            else:
                print(f'{futures[fut]} is done')

    for vm in VMs:
        os.mkdir(f"distribution-dir/{vm}")
        subprocess.check_call(["scp", f"{vm}:Projects/pyobjc/distribution-dir/*", f"distribution-dir/{vm}"])
        for fn in os.listdir(f"distribution-dir/{vm}"):
            if os.path.exists(f"distribution-dir/{fn}"):
                continue
            os.rename(f"distribution-dir/{vm}/{fn}", f"distribution-dir/{fn}")

        shutil.rmtree(f"distribution-dir/{vm}")

    print()
    print("Collected files")
    print("===============")
    print()
    names = { nm.split('-')[0] for nm in os.listdir('distribution-dir') }
    for nm in sorted(names):
        if nm == 'pyobjc': continue
        pattern = nm.replace('-', '?') + '-*'
        print("{}:".format(nm))
        for fn in sorted(files_matching(pattern, 'distribution-dir')):
            print("  {}".format(fn))
        print()

    print()
    end_time = time.time()
    print(f"Building took {end_time - start_time:.1f} seconds")


if __name__ == "__main__":
    main()
