#!/usr/bin/env python

import argparse
import distutils.spawn
import os
import re
import signal
import subprocess
import sys

def main():

    # listen for ctrl-c
    signal.signal(signal.SIGINT, handler)

    # parse command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("-f", "--fast", action="store_true", help="skip autoupdate")
    parser.add_argument("directory", default=os.getcwd(), nargs="?", help="directory to mount")
    args = vars(parser.parse_args())

    # check for docker
    if not distutils.spawn.find_executable("docker"):
        parser.error("docker not installed")

    # ensure directory exists
    directory = os.path.realpath(args["directory"])
    if not os.path.isdir(directory):
        parser.error("{}: no such directory".format(args["directory"]))

    # update image
    if not args["fast"]:
        subprocess.call(["docker", "pull", "cs50/cli"])

    # check for running containers
    stdout = subprocess.check_output([
        "docker", "ps",
            "--all",
            "--filter",
            "volume={}".format(directory),
            "--format", "{{.ID}}\t{{.Image}}\t{{.RunningFor}}"
            ]).decode("utf-8")
    containers = []
    for line in stdout.rstrip().splitlines():
        ID, Image, RunningFor = line.split("\t")
        if Image == "cs50/cli":
            containers.append((ID, RunningFor.lower()))

    # ask whether to use a running container
    if containers:
        print("{} is already mounted in {} {}.".format(directory, len(containers), "containers" if len(containers) > 1 else "container"))
    for ID, RunningFor in containers:
        while True:
            stdin = input("New shell in {}, running for {}? [Y] ".format(ID, RunningFor))
            if re.match("^\s*(?:y|yes)?\s*$", stdin, re.I):
                subprocess.call([
                    "docker", "exec",
                        "--interactive",
                        "--tty",
                        ID,
                        "bash",
                        "--login"
                        ])
                sys.exit(0)
            else:
                break

    # mount directory in new container
    subprocess.call([
        "docker", "run",
            "--interactive",
            "--publish-all",
            "--rm",
            "--security-opt", "seccomp=unconfined", # http://stackoverflow.com/questions/35860527/warning-error-disabling-address-space-randomization-operation-not-permitted#comment62818827_35860527
            "--tty",
            "--volume", directory + ":/root",
            "--workdir", "/root",
            "cs50/cli"
            ])

def handler(number, frame):
    """Handle SIGINT."""
    print("")
    sys.exit(0)

if __name__ == "__main__":
    if sys.version_info < (2, 7):
        sys.exit("CS50 CLI requires Python 2.7 or higher")
    if sys.version_info.major == 2:
        input = raw_input
    main()
