#!/usr/bin/python3

"""CLI for submitting tasks to Retrace Server."""

import argparse
import logging
import os
import shutil
import socket
import sys
import tarfile
import tempfile
import time
from pathlib import Path
from typing import Any, Dict, Optional, Tuple

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from requests_gssapi import HTTPSPNEGOAuth, DISABLED

from retrace.retrace import add_snapshot_suffix


FALLBACK_SERVER = "https://retrace.fedoraproject.org"
TASK_COREDUMP, TASK_DEBUG, TASK_VMCORE, TASK_COREDUMP_INTERACTIVE, \
    TASK_VMCORE_INTERACTIVE = range(5)


def ticket_check() -> bool:
    """Check if the user has a valid kerberose ticket."""
    return not os.system("klist -s")


def prepare_tar(args: Dict[str, Any]) -> Path:
    """Create tar file containg all necessary files."""
    LOGGER.info("Preparing tar")
    corefile = Path(args["COREFILE"])
    tmpdir = Path(tempfile.mkdtemp())
    tar_name = tmpdir / "archive.tar.gz"
    with tarfile.open(tar_name, "w:gz") as tar_file:
        for itm in ["kernelver", "os_release", "package", "executable"]:
            if itm in args.keys() and args[itm]:
                LOGGER.info("Adding '%s' into tar", format(itm))
                fl_path = tmpdir / itm
                with fl_path.open("w") as fld:
                    fld.write(args[itm])
                tar_file.add(str(fl_path), arcname=itm)

        LOGGER.info("Adding '%s' as '%s' into tar", corefile, args['task_type'])
        if not corefile.is_file():
            print(f"'{corefile}' does not exists")
            sys.exit(1)

        file_name = add_snapshot_suffix(args["task_type"], corefile)
        tar_file.add(str(corefile), arcname=file_name)

        if args["vmem"]:
            vmem = Path(args["vmem"])
            vmem_file = args["task_type"] + ".vmem"
            LOGGER.info("Adding '%s' as '%s' into tar", vmem, vmem_file)

            if not vmem.is_file():
                print("'{0}' does not exists".format(vmem))
                sys.exit(1)

            tar_file.add(str(vmem), arcname=vmem_file)

    LOGGER.info("Tar file created as '%s'", tar_name)
    return tar_name


def check_response(response, kill: bool = True) -> bool:
    """Test return code of response.

    If @kill is True. then when code differ from 200 exit the whole script.
    """
    if response.status_code not in [200, 201]:
        LOGGER.info("Code %s was returned. Headers:\n%s\nText:\n%s\n",
                    response.status_code, response.headers, response.text)
        if kill:
            print("Status code {0} was returned with message: '{1}'"
                  .format(response.status_code, response.text))
            sys.exit(1)
        else:
            return True
    return False


def parse_task_id(response) -> str:
    """Parse Task_ID from manager page."""
    for line in response.text.split("\n"):
        if "<title>Task #" in line:
            return line.split()[1][1:]
    return "unknown"


def parse_status(response) -> str:
    """Parse status from manager page."""
    lines = response.text.split("\n")
    for i, line in enumerate(lines):
        if "<th>Status:</th>" in line:
            return lines[i + 1].strip()[4:-5]
    return "unknown"


def parse_md5sum(response) -> str:
    """Parse md5sum from manager page."""
    lines = response.text.split("\n")
    for line in lines:
        if "<th>Md5sum:</th>" in line:
            return line[line.find("<td>") + 4:]
    return "Md5sum not calculated. Not yet downloaded or md5sum not requested."


def parse_email(response) -> Optional[str]:
    """Parse email from manager page."""
    key_string = "Update e-mail(s)"
    lines = response.text.split("\n")
    for line in lines:
        if key_string in line:
            first = line.find("value=") + 7
            last = line.find('"', first)
            candidate = line[first:last]
            if candidate == key_string:
                return "Email is not set."
            return candidate
    return None


def parse_caseno(response) -> Optional[str]:
    """Parse caseno from manager page."""
    key_string = "Update case no."
    lines = response.text.split("\n")
    for line in lines:
        if key_string in line:
            first = line.find("value=") + 7
            last = line.find('"', first)
            candidate = line[first:last]
            if candidate == key_string:
                return "Case number is not set."
            return candidate
    return None

def parse_bugzillano(response) -> Optional[str]:
    """Parse bugzillano from manager page."""
    key_string = "Update bugzilla no."
    lines = response.text.split("\n")
    for line in lines:
        if key_string in line:
            first = line.find("value=") + 7
            last = line.find('"', first)
            candidate = line[first:last]
            if candidate == key_string:
                return "Bugzilla number is not set."
            return candidate
    return None

def restart_existing_task(args: Dict[str, Any]) -> None:
    """Restart exiting task."""
    LOGGER.info("Restarting task from server %s",
                args["server"] + "/manager/" + args["TASK_ID"])
    server = args["server"] + "/manager/" + args["TASK_ID"] + "/restart"
    payload = {}
    for itm in ["kernelver", "debug", "caseno", "bugzillano"]:
        if itm in args.keys():
            payload[itm] = args[itm]
    if args["email"]:
        payload["notify"] = args["email"]
    res = requests.post(server,
                        data=payload,
                        verify=(not args["no_verify"]),
                        auth=args["kerberos"])

    check_response(res)

    print("Restarted task '{0}'"
          .format(args["TASK_ID"]))

def create_new_task(args: Dict[str, Any]) -> Tuple[int, Optional[str]]:
    """Start new task."""
    if args["task_input"] == "http":
        LOGGER.info("Starting new http task")
        if args["task_type"] == "coredump":
            if args["interactive"]:
                task_type = TASK_COREDUMP_INTERACTIVE
            else:
                task_type = TASK_COREDUMP
        elif args["interactive"]:
            task_type = TASK_VMCORE_INTERACTIVE
        else:
            task_type = TASK_VMCORE

        if args["vmem"] and task_type not in [TASK_VMCORE, TASK_VMCORE_INTERACTIVE]:
            LOGGER.warning("Ignoring: %s, option is only viable with vmcores.",
                           args["vmem"])
            args["vmem"] = None

        LOGGER.info("Task_type: %s", task_type)

        tar_name = Path(prepare_tar(args))
        tar_size = tar_name.stat().st_size
        LOGGER.info("Tar size: %s", tar_size)

        headers = {"Content-Type": "application/x-tar",
                   "Content-Length": str(tar_size),
                   "X-Task-Type": str(task_type),
                   "Connection": "close"}

        request = requests.Request("POST",
                                   args["server"] + "/create",
                                   headers=headers)

        LOGGER.info("Connecting to %s", args["server"] + "/create")

        prepped = request.prepare()
        with open(tar_name, "rb") as fld:
            prepped.body = fld.read(tar_size)

        session = requests.Session()

        res = session.send(prepped,
                           stream=True,
                           verify=(not args["no_verify"]))

        shutil.rmtree(tar_name.parent)

        check_response(res)

        task_id = res.headers["X-Task-ID"]
        task_password = res.headers["X-Task-Password"]

        print("Task created")
        print("Task ID: {0}".format(task_id))
        print("Task password: {0}".format(task_password))
        return (task_id, task_password)

    if args["task_input"] == "manager":
        args["COREFILE"] = Path(args["COREFILE"]).resolve().as_uri()
        if args["vmem"]:
            args["vmem"] = Path(args["vmem"]).resolve().as_uri()

        LOGGER.info("Starting new manager task")
        server = args["server"] + "/manager/"
        payload = {"custom_url": args["COREFILE"]}
        if args["vmem"]:
            payload["vmem-check"] = "on" if args["vmem"] else "off"
            payload.update({"custom_vmem_url": args["vmem"]})

        payload["md5sum"] = "off" if args["no_md5"] else "on"
        for itm in ["debug", "kernelver", "task_type", "os_release", "package", "executable"]:
            if itm in args.keys():
                payload[itm] = args[itm]

        LOGGER.info("Connecting to %s", server + "__custom__")

        res = requests.post(server + "__custom__",
                            data=payload,
                            verify=(not args["no_verify"]),
                            auth=args["kerberos"])

    elif args["task_input"] == "ftp":
        LOGGER.info("Starting new ftp task")
        server = args["server"] + "/manager/"
        payload = {"md5sum": "off" if args["no_md5"] else "on"}
        for itm in ["debug", "kernelver", "task_type", "os_release", "package", "executable"]:
            if itm in args.keys():
                payload[itm] = args[itm]

        if args["vmem"]:
            payload["vmem-check"] = "on" if args["vmem"] else "off"
            payload.update({"custom_vmem_url": args["vmem"]})

        LOGGER.info("Connecting to server %s",
                    server + args["COREFILE"] + "/start")
        res = requests.get(server + args["COREFILE"] + "/start",
                           params=payload,
                           verify=(not args["no_verify"]),
                           auth=args["kerberos"])

    check_response(res)
    task_id = parse_task_id(res)
    print("Task created on {0}"
          .format(server + task_id))

    ARGS["TASK_ID"] = task_id
    ARGS["password"] = None

    if ARGS["email"]:
        update_email(ARGS)

    if ARGS["caseno"]:
        update_caseno(ARGS)

    if ARGS["bugzillano"]:
        update_bugzillano(ARGS)

    return (task_id, None)


def get_status(args: Dict[str, Any]) -> str:
    """Get current task's status."""
    if args["password"]:
        LOGGER.info("Getting status from http task on server %s",
                    args["server"] + "/" + args["TASK_ID"])
        server = args["server"] + "/" + args["TASK_ID"]
        headers = {"X-Task-Password": args["password"]}
        res = requests.get(server,
                           headers=headers,
                           verify=(not args["no_verify"]),
                           auth=args["kerberos"])

        check_response(res)
        status = res.text
        return status

    LOGGER.info("Getting status from manager/ftp task on server %s",
                args["server"] + "/manager/" + args["TASK_ID"])
    server = args["server"] + "/manager/" + args["TASK_ID"]
    res = requests.get(server,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    check_response(res)
    status = parse_status(res)
    return status


def get_md5sum(args: Dict[str, Any]) -> bool:
    """Get md5sum of uploaded file."""
    # Only supported for manager tasks
    if args["password"]:
        print("Md5sum are supported for manager and ftp tasks")
        sys.exit(1)

    LOGGER.info("Getting md5sum from server %s",
                args["server"] + "/manager/" + args["TASK_ID"])

    server = args["server"] + "/manager/" + args["TASK_ID"]
    res = requests.get(server,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    if check_response(res, False):
        print("Error: md5sum is only supported for manager and ftp tasks")
        return False
    md5sum = parse_md5sum(res)
    print(md5sum)
    return True


def get_email(args: Dict[str, Any]) -> bool:
    """Get email of a task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Emails are supported for manager and ftp tasks")
        sys.exit(1)

    LOGGER.info("Getting email from server %s",
                args["server"] + "/manager/" + args["TASK_ID"])

    server = args["server"] + "/manager/" + args["TASK_ID"]
    res = requests.get(server,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    if check_response(res, False):
        print("Error: email is only supported for manager and ftp tasks")
        return False
    email = parse_email(res)
    print(email)
    return True


def get_caseno(args: Dict[str, Any]) -> bool:
    """Get case number of a task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Case numbers are supported for manager and ftp tasks")
        sys.exit(1)

    LOGGER.info("Getting case number from server %s",
                args["server"] + "/manager/" + args["TASK_ID"])

    server = args["server"] + "/manager/" + args["TASK_ID"]
    res = requests.get(server,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    if check_response(res, False):
        print("Error: caseno is only supported for manager and ftp tasks")
        return False
    caseno = parse_caseno(res)
    print(caseno)
    return True

def get_bugzillano(args: Dict[str, Any]) -> bool:
    """Get bugzilla number of a task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Bugzilla numbers are supported for manager and ftp tasks")
        sys.exit(1)

    LOGGER.info("Getting bugzilla number from server %s",
                args["server"] + "/manager/" + args["TASK_ID"])

    server = args["server"] + "/manager/" + args["TASK_ID"]
    res = requests.get(server,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    if check_response(res, False):
        print("Error: bugzillano is only supported for manager and ftp tasks")
        return False
    bugzillano = parse_bugzillano(res)
    print(bugzillano)
    return True

def get_backtrace(args: Dict[str, Any]) -> bool:
    """Get a backtrace of the task."""
    if args["password"]:
        server = args["server"] + "/" + args["TASK_ID"] + "/backtrace"
        headers = {"X-Task-Password": args["password"]}

    else:
        server = args["server"] + "/manager/" + args["TASK_ID"] + "/backtrace"
        headers = {}

    LOGGER.info("Getting backtrace from server %s", server)

    res = requests.get(server,
                       headers=headers,
                       verify=(not args["no_verify"]),
                       auth=args["kerberos"])

    if check_response(res, False):
        if res.text == "There is no backtrace for the specified task":
            print("No backtrace. Check status if task is running or failed.")
            return False

        print("Error: {0}".format(res.text))
        sys.exit(1)

    with open("backtrace", "w") as fld:
        fld.write(res.text)
    print("Backtrace saved into 'backtrace' file")
    return True


def run_batch(args: Dict[str, Any]) -> None:
    """Run the whole retrace process in one go."""
    task_id, password = create_new_task(args)
    args["password"] = password
    args["TASK_ID"] = task_id
    last_status = ""
    new_status = get_status(args)
    while True:
        print(new_status)
        last_status = new_status
        if new_status == "Retrace job finished successfully":
            break
        if new_status == "Retrace job failed":
            sys.exit(1)
        while new_status == last_status:
            time.sleep(10)
            new_status = get_status(args)

    get_backtrace(args)


def update_email(args: Dict[str, Any]) -> None:
    """Update the email address of the task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Email notification only supported for manager and ftp tasks")
        sys.exit(1)
    server = args["server"] + "/manager/" + args["TASK_ID"] + "/notify"
    res = requests.post(server,
                        data={"notify": args["email"]},
                        verify=(not args["no_verify"]),
                        auth=args["kerberos"])

    check_response(res)
    print("Added email address '{0}' to the task '{1}'"
          .format(args["email"], args["TASK_ID"]))


def update_caseno(args: Dict[str, Any]) -> None:
    """Update case number of the task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Case number is only supported for manager and ftp tasks")
        sys.exit(1)
    server = args["server"] + "/manager/" + args["TASK_ID"] + "/caseno"
    res = requests.post(server,
                        data={"caseno": args["caseno"]},
                        verify=(not args["no_verify"]),
                        auth=args["kerberos"])

    check_response(res)
    print("Added case number '{0}' to the task '{1}'"
          .format(args["caseno"], args["TASK_ID"]))

def update_bugzillano(args: Dict[str, Any]) -> None:
    """Update bugzilla number of the task."""
    # Only supported for manager tasks
    if args["password"]:
        print("Case number is only supported for manager and ftp tasks")
        sys.exit(1)
    server = args["server"] + "/manager/" + args["TASK_ID"] + "/bugzillano"
    res = requests.post(server,
                        data={"bugzillano": args["bugzillano"]},
                        verify=(not args["no_verify"]),
                        auth=args["kerberos"])

    check_response(res)
    print("Added bugzilla number '{0}' to the task '{1}'"
          .format(args["bugzillano"], args["TASK_ID"]))

if __name__ == "__main__":
    # parse arguments
    PARSER = argparse.ArgumentParser(description=("Create, watch and set"
                                                  "tasks through commandline"))
    TASK_PARSER = PARSER.add_subparsers(dest="task_action")
    for cmd in ["create", "batch"]:
        tmp = TASK_PARSER.add_parser(cmd)
        type_group = tmp.add_mutually_exclusive_group()
        type_group.add_argument("-u", "--userspace_core", action="store_const",
                                dest="task_type", const="coredump",
                                help="Retrace userspace coredump")
        type_group.add_argument("-k", "--kernel_vmcore", action="store_const",
                                dest="task_type", const="vmcore",
                                help="Retrace kernel vmcore")
        tmp.add_argument("COREFILE",
                         help="File to be retraced")

        input_group = tmp.add_mutually_exclusive_group()
        input_group.add_argument("-t", "--http", action="store_const",
                                 dest="task_input", const="http",
                                 help="Submit local corefile through http")
        input_group.add_argument("-m", "--manager", action="store_const",
                                 dest="task_input", const="manager",
                                 help=("Submit corefile URL that is wget-able"
                                       "or local server file"))
        input_group.add_argument("-f", "--ftp", action="store_const",
                                 dest="task_input", const="ftp",
                                 help=("Submit corefile that is accessible"
                                       "from FTP set on server"))

        tmp.add_argument("-i", "--interactive", action="store_true",
                         help="Create interactive task")
        tmp.add_argument("-d", "--no-md5", action="store_true",
                         help="Do not calculate md5sum on the archive")
        tmp.add_argument("-s", "--server",
                         help="URL for retrace-server")
        tmp.add_argument("-n", "--no-verify", action="store_true",
                         help="Do not verify certificate")
        tmp.add_argument("-v", "--verbose", action="store_const",
                         default=logging.WARNING, const=logging.DEBUG)

        tmp.add_argument("--vmem", metavar="VMEM",
                         help="Virtual memory file for vmcore snapshot")

        tmp.add_argument("-r", "--kernelver",
                         help="Version of kernel in vmcore")
        tmp.add_argument("-o", "--os_release",
                         help="Version of operating system")
        tmp.add_argument("-p", "--package",
                         help="Version of crashed package")
        tmp.add_argument("-x", "--executable",
                         help="Crash executable")

        tmp.add_argument("-e", "--email",
                         help=("Set email to the task."
                               "Only takes affect with -f or -m"))
        tmp.add_argument("-c", "--caseno",
                         help=("Set caseno to the task."
                               "Only takes affect with -f or -m"))
        tmp.add_argument("-bz", "--bugzillano",
                         help=("Set bugzillano to the task."
                               "Only takes affect with -f or -m"))

    TMP = TASK_PARSER.add_parser("get")
    TMP.add_argument("TASK_ID",
                     help="ID of existing task")
    TMP.add_argument("-p", "--password",
                     help="Password of the task")
    TMP.add_argument("-s", "--server",
                     help="URL for retrace-server")
    TMP.add_argument("-n", "--no-verify", action="store_true",
                     help="Do not verify certificate")
    TMP.add_argument("-v", "--verbose", action="store_const",
                     default=logging.WARNING, const=logging.DEBUG)
    GET_TYPE = TMP.add_mutually_exclusive_group()
    GET_TYPE.add_argument("-t", "--status", action="store_const",
                          dest="get_type", const="status",
                          help="Get current status of the task.")
    GET_TYPE.add_argument("-b", "--backtrace", action="store_const",
                          dest="get_type", const="backtrace",
                          help="Get backtrace of the task.")
    GET_TYPE.add_argument("-m", "--md5sum", action="store_const",
                          dest="get_type", const="md5sum",
                          help="Get md5sum of the task.")
    GET_TYPE.add_argument("-e", "--email", action="store_const",
                          dest="get_type", const="email",
                          help="Get set email of the task.")
    GET_TYPE.add_argument("-c", "--caseno", action="store_const",
                          dest="get_type", const="caseno",
                          help="Get set case number of the task.")
    GET_TYPE.add_argument("-bz", "--bugzillano", action="store_const",
                          dest="get_type", const="bugzillano",
                          help="Get set bugzilla number of the task.")

    TMP = TASK_PARSER.add_parser("set")
    TMP.add_argument("TASK_ID",
                     help="ID of existing task")
    TMP.add_argument("-p", "--password",
                     help="Password of the task")
    TMP.add_argument("-s", "--server",
                     help="URL for retrace-server")
    TMP.add_argument("-n", "--no-verify", action="store_true",
                     help="Do not verify certificate")
    TMP.add_argument("-v", "--verbose", action="store_const",
                     default=logging.WARNING, const=logging.DEBUG)
    TMP.add_argument("-c", "--caseno",
                     help="Set case number of the task.")
    TMP.add_argument("-e", "--email",
                     help="Set email to the task.")
    TMP.add_argument("-bz", "--bugzillano",
                     help="Set bugzilla number of the task.")

    TMP = TASK_PARSER.add_parser("restart")
    TMP.add_argument("TASK_ID",
                     help="ID of existing task")
    TMP.add_argument("-n", "--no-verify", action="store_true",
                     help="Do not verify certificate")
    TMP.add_argument("-s", "--server",
                     help="URL for retrace-server")
    TMP.add_argument("-v", "--verbose", action="store_const",
                     default=logging.WARNING, const=logging.DEBUG)
    TMP.add_argument("-bz", "--bugzillano",
                     help="Set bugzilla number of the task.")
    TMP.add_argument("-c", "--caseno",
                     help="Set case number of the task.")
    TMP.add_argument("-e", "--email",
                     help="Set email to the task.")
    TMP.add_argument("-r", "--kernelver",
                     help="Version of kernel in vmcore")

    ARGS = vars(PARSER.parse_args())

    if len(ARGS) == 1:
        PARSER.print_help(sys.stderr)
        sys.exit(1)

    # if not verifying certificates, suppress warning
    if ARGS["no_verify"]:
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

    # create logger
    logging.basicConfig(level=ARGS["verbose"])
    LOGGER = logging.getLogger()

    # If verbose was given, turn on debug for task commands
    if ARGS["verbose"] != logging.WARNING:
        ARGS["debug"] = "on"

    # check kerberos
    if ticket_check():
        LOGGER.info("Kerberos ticket is valid.")
        ARGS["kerberos"] = HTTPSPNEGOAuth(mutual_authentication=DISABLED)
    else:
        ARGS["kerberos"] = None

    # Try guessing type of task if no specified
    if ARGS["task_action"] in ["create", "batch"] and not ARGS["task_input"]:
        # If the file does not exist locally
        if not Path(ARGS["COREFILE"]).is_file():
            # and server not know
            if not ARGS["server"]:
                LOGGER.info("Defaulting to ftp task")
                ARGS["task_input"] = "ftp"
            else:
                LOGGER.info("Defaulting to manager task")
                ARGS["task_input"] = "manager"
        else:
            if not ARGS["server"]:
                LOGGER.info("Defaulting to manager task")
                ARGS["task_input"] = "manager"
            else:
                LOGGER.info("Defaulting to http task")
                ARGS["task_input"] = "http"

    # Default to localhost if no server was specified.
    if not ARGS["server"]:
        ARGS["server"] = "https://" + socket.gethostname()

    # Check that we are able to connect to the server.
    LOGGER.info("Trying to connect to ‘%s’...", ARGS["server"])
    try:
        req = requests.get(ARGS["server"],
                           verify=(not ARGS["no_verify"]),
                           auth=ARGS["kerberos"])
        if req.status_code == 401:
            print("Authentication failed for ‘{}’".format(ARGS["server"]))
            print("If the server requires Kerberos authentication, please use"
                  " the ‘kinit’ command to obtain a valid ticket first.")
            sys.exit(1)
        if req.status_code != 200:
            raise requests.exceptions.ConnectionError
    except requests.exceptions.SSLError as ex:
        if "debug" in ARGS:
            LOGGER.error("SSLError: '%s'", str(ex))
        LOGGER.error("SSL error connecting to {}: try adding '-v' to see details"
                     " or '--no-verify' for an expired certificate.".format(ARGS["server"]))
        sys.exit(1)
    except requests.exceptions.RequestException as ex:
        if "debug" in ARGS:
            LOGGER.error("Requests generic exception: '%s'", str(ex))
        LOGGER.error("Could not connect to server ‘%s’. Falling back to ‘%s’",
                    ARGS["server"], FALLBACK_SERVER)
        ARGS["server"] = FALLBACK_SERVER

    if ARGS["task_action"] == "create":
        create_new_task(ARGS)

    if ARGS["task_action"] == "batch":
        run_batch(ARGS)

    if ARGS["task_action"] == "get":
        if ARGS["get_type"] == "md5sum":
            get_md5sum(ARGS)
        elif ARGS["get_type"] == "backtrace":
            get_backtrace(ARGS)
        elif ARGS["get_type"] == "email":
            get_email(ARGS)
        elif ARGS["get_type"] == "caseno":
            get_caseno(ARGS)
        elif ARGS["get_type"] == "bugzillano":
            get_bugzillano(ARGS)
        else:
            print("Status: {0}".format(get_status(ARGS)))

    if ARGS["task_action"] == "set":
        if ARGS["email"]:
            update_email(ARGS)
        if ARGS["caseno"]:
            update_caseno(ARGS)
        if ARGS["bugzillano"]:
            update_bugzillano(ARGS)

    if ARGS["task_action"] == "restart":
        restart_existing_task(ARGS)
