"""``cubi-tk snappy kickoff``: kickoff SNAPPY pipeline."""

import argparse
import os
import subprocess
import typing

from logzero import logger
from toposort import toposort

from . import common

from cubi_tk.exceptions import ParseOutputException


def run(
    args, _parser: argparse.ArgumentParser, _subparser: argparse.ArgumentParser
) -> typing.Optional[int]:
    logger.info("Try to find SNAPPY pipeline directory...")
    try:
        path = common.find_snappy_root_dir(args.path or os.getcwd(), common.DEPENDENCIES.keys())
    except common.CouldNotFindPipelineRoot:
        return 1

    # TODO: this assumes standard naming which is a limitation...
    logger.info("Looking for pipeline directories (assuming standard naming)...")
    logger.debug("Looking in %s", path)
    step_set = {name for name in common.DEPENDENCIES if (path / name).exists()}
    steps: typing.List[str] = []
    for names in toposort({k: set(v) for k, v in common.DEPENDENCIES.items()}):
        steps += [name for name in names if name in step_set]
    logger.info("Will run the steps: %s", ", ".join(steps))

    logger.info("Submitting with sbatch...")
    jids: typing.Dict[str, str] = {}
    for step in steps:
        dep_jids = [jids[dep] for dep in common.DEPENDENCIES[step] if dep in jids]
        cmd = ["sbatch"]
        if dep_jids:
            cmd += ["--dependency", "afterok:%s" % ":".join(map(str, dep_jids))]
        cmd += ["pipeline_job.sh"]
        logger.info("Submitting step %s: %s", step, " ".join(cmd))
        if args.dry_run:
            jid = "<%s>" % step
        else:
            stdout_raw = subprocess.check_output(cmd, cwd=str(path / step), timeout=args.timeout)
            stdout = stdout_raw.decode("utf-8")
            if not stdout.startswith("Submitted batch job "):
                raise ParseOutputException("Did not understand sbatch output: %s" % stdout)
            jid = stdout.split()[-1]
        logger.info(" => JID: %s", jid)
        jids[step] = jid

    return None


def setup_argparse(parser: argparse.ArgumentParser) -> None:
    """Setup argument parser for ``cubi-tk snappy pull-sheet``."""
    parser.add_argument("--hidden-cmd", dest="snappy_cmd", default=run, help=argparse.SUPPRESS)

    parser.add_argument(
        "--dry-run",
        "-n",
        default=False,
        action="store_true",
        help="Perform dry-run, do not do anything.",
    )

    parser.add_argument(
        "--timeout", default=10, type=int, help="Number of seconds to wait for commands."
    )

    parser.add_argument(
        "path",
        nargs="?",
        help="Path into SNAPPY directory (below a directory containing .snappy_pipeline).",
    )

[((19, 4, 19, 59), 'logzero.logger.info', 'logger.info', ({(19, 16, 19, 58): '"""Try to find SNAPPY pipeline directory..."""'}, {}), "('Try to find SNAPPY pipeline directory...')", False, 'from logzero import logger\n'), ((26, 4, 26, 81), 'logzero.logger.info', 'logger.info', ({(26, 16, 26, 80): '"""Looking for pipeline directories (assuming standard naming)..."""'}, {}), "('Looking for pipeline directories (assuming standard naming)...')", False, 'from logzero import logger\n'), ((27, 4, 27, 39), 'logzero.logger.debug', 'logger.debug', ({(27, 17, 27, 32): '"""Looking in %s"""', (27, 34, 27, 38): 'path'}, {}), "('Looking in %s', path)", False, 'from logzero import logger\n'), ((34, 4, 34, 44), 'logzero.logger.info', 'logger.info', ({(34, 16, 34, 43): '"""Submitting with sbatch..."""'}, {}), "('Submitting with sbatch...')", False, 'from logzero import logger\n'), ((51, 8, 51, 39), 'logzero.logger.info', 'logger.info', ({(51, 20, 51, 33): '""" => JID: %s"""', (51, 35, 51, 38): 'jid'}, {}), "(' => JID: %s', jid)", False, 'from logzero import logger\n'), ((21, 56, 21, 67), 'os.getcwd', 'os.getcwd', ({}, {}), '()', False, 'import os\n'), ((49, 22, 49, 91), 'cubi_tk.exceptions.ParseOutputException', 'ParseOutputException', ({(49, 43, 49, 90): "('Did not understand sbatch output: %s' % stdout)"}, {}), "('Did not understand sbatch output: %s' % stdout)", False, 'from cubi_tk.exceptions import ParseOutputException\n')]