"""
Read snakefood dependencies and output a visual graph.
"""
# This file is part of the Snakefood open source package.
# See http://furius.ca/snakefood/ for licensing details.

import sys, os
from os.path import *

from snakefood.depends import read_depends, eliminate_redundant_depends

graph_settings = [
        ("rankdir", "LR"),
        ("overlap", "scale"),
        ("size", "8,10"),
        ("ratio", "fill"),
        ("fontsize", "16"),
        ("fontname", "Helvetica"),
        ("clusterrank", "local")
]

prefix = '''
# This file was generated by sfood-graph.

strict digraph "dependencies" {
    graph [
%s
        ]

       node [
           fontsize=%s
           shape=ellipse
           // style=filled
           // shape=box
       ];

'''
postfix = '''

}
'''

def graph(pairs, write, fontsize, dpi=-1):
    "Given (from, to) pairs of (root, fn) files, output a dot graph."
    gs = list(graph_settings) # copy global
    if dpi > 0:
        gs.append(("dpi", str(dpi)))
    gss = ',\n'.join(['           {}="{}"'.format(c, v) for (c,v) in gs])
    write(prefix % (gss, fontsize))
    lines = []
    for (froot, f), (troot, t) in pairs:
        if opts.pythonify_filenames:
            f = normpyfn(f)
            t = normpyfn(t)
        if opts.full_pathnames:
            f = join(froot, f)
            if troot:
                t = join(troot, t)
        if troot is None:
            write('"%s"  [style=filled];\n' % f)
        else:
            write('"%s" -> "%s";\n' % (f, t))
    write(postfix)

def normpyfn(fn):
    "Normalize the python filenames for output."
    if fn is None:
        return fn
    if fn.endswith('.py'):
        fn = fn[:-3]
    fn = fn.replace(os.sep, '.')
    return fn

def main():
    import optparse
    parser = optparse.OptionParser(__doc__.strip())

    parser.add_option('-f', '--full-pathnames', '--full', action='store_true',
                      help="Output the full pathnames, not just the relative.")

    parser.add_option('-p', '--pythonify-filenames', '--remove-extensions',
                      action='store_true',
                      help="Remove filename extensions in the graph and "
                      "replace slashes with dots.")

    parser.add_option('-r', '--redundant', action='store_false', default=True,
                      help="Do not eliminate redundant dependencies.")

    parser.add_option('--fontsize', action='store', type='int',
                      default=10,
                      help="The size of the font to use for nodes.")

    parser.add_option('--dpi', action='store', type='int',
                      default=-1,
                      help="Resolution to use for graph.")

    global opts
    opts, args = parser.parse_args()

    if not args:
        args = ['-']
    for fn in args:
        if fn == '-':
            f = sys.stdin
        else:
            f = open(fn)
        depends = read_depends(f)
        if opts.redundant:
            depends = eliminate_redundant_depends(depends)
        graph(depends, sys.stdout.write,
            opts.fontsize, opts.dpi)
