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

# Copyright 2015 by Leipzig University Library, http://ub.uni-leipzig.de
#                   The Finc Authors, http://finc.info
#                   Martin Czygan, <martin.czygan@uni-leipzig.de>
#
# This file is part of some open source application.
#
# Some open source application is free software: you can redistribute
# it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, either
# version 3 of the License, or (at your option) any later version.
#
# Some open source application is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
#
# @license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>

"""
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

import collections
import sys

from luigi.cmdline_parser import CmdlineParser
from luigi.parameter import MissingParameterException
from luigi.task import Register
from luigi.task_register import TaskClassNotFoundException

from siskin.sources import *
from siskin.utils import random_string
from siskin.workflows import *

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

# These tasks are rendered with all parameters.
INCLUDE_FULLY = set(['Executable', 'FTPMirror'])


def iterdeps(task):
    """
    Collect dependencies recursively and store them in the global graph `g`.
    """
    for dependency in task.deps():

        if task.task_family in INCLUDE_FULLY:
            taskname = (task.task_id,)
        else:
            taskname = (task.task_family,)

        if dependency.task_family in INCLUDE_FULLY:
            depname = (dependency.task_id,)
        else:
            depname = (dependency.task_family,)

        g[taskname].add(depname)
        if dependency not in seen:
            seen.add(dependency)
            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.items():
        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__':
    try:
        parser = CmdlineParser(sys.argv[1:])
        task = parser.get_task_obj()
        iterdeps(task)
        print(simpleformat(g))
    except MissingParameterException as err:
        print('missing parameter: %s' % err, file=sys.stderr)
        sys.exit(1)
    except TaskClassNotFoundException as err:
        print(err, file=sys.stderr)
        sys.exit(1)
