#!/usr/bin/env python
# coding: utf-8
# pylint: disable=F0401,C0111,W0232,E1101,E1103,C0301

"""
Turn task dependencies into pretty graphs.

Usage: taskdeps-dot TASKNAME

Example outputs images: http://imgur.com/a/12Dag, http://i.imgur.com/8bFvSvN.gif
"""

from __future__ import print_function
from gluish.utils import pairwise, random_string
from luigi.task import id_to_name_and_params
from luigi.task import Register
from siskin.sources import *
from siskin.workflows import *
import collections
import re
import sys

# task -> deps graph
g = collections.defaultdict(set)

def iterdeps(task):
    """
    Collect dependencies recursively and store them in the global graph `g`.
    """
    for dependency in task.deps():
        tn, tp = id_to_name_and_params(task.task_id)
        dn, dp = id_to_name_and_params(dependency.task_id)

        tt = (tn, frozenset(tp.items()))
        dd = (dn, frozenset(dp.items()))

        g[tt].add(dd)
        iterdeps(dependency)

def simpleformat(graph):
    """ Format graph as dot. Omit parameters - makes some graphs much smaller. Example: http://imgur.com/a/hxJqv """
    s = 'digraph %s {' % random_string()
    for task, deps in g.iteritems():
        for dep in deps:
            s = s + """\t"%s" [fontname="Helvetica"]; """ % task[0]
            s = s + """\t"%s" [fontname="Helvetica"]; """ % dep[0]
            s = s + """\t"%s" -> "%s"; """ % (task[0], dep[0])
            s = s + "\n"
    s = s + '}'
    return s

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('taskdeps-dot TASKNAME', file=sys.stderr)
        sys.exit(1)

    taskname = sys.argv[1]

    if not taskname in Register.task_names():
        print('no such task: %s' % taskname, file=sys.stderr)
        sys.exit(1)

    # workaround for #1
    ignore = ['--local-scheduler', '--no-lock', '--parallel-scheduling',
              '--assistant', '--scheduler-record-task-history']
    args = [arg for arg in sys.argv[2:] if not arg in ignore]

    kwargs = dict((k.lstrip('--').replace('-', '_'), v) for k, v in pairwise(args))

    klass = Register.get_task_cls(taskname)
    task = klass(**kwargs)
    iterdeps(task)

    print(simpleformat(g))
