#!/usr/bin/env python3

# Simple graph query utility
# useful for getting answers from .dot files produced by bitbake -g
#
# Written by: Paul Eggleton <paul.eggleton@linux.intel.com>
#
# Copyright 2013 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import os
import argparse

scripts_lib_path = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'lib'))
sys.path.insert(0, scripts_lib_path)
import argparse_oe


def get_path_networkx(dotfile, fromnode, tonode):
    try:
        import networkx
    except ImportError:
        print('ERROR: Please install the networkx python module')
        sys.exit(1)

    graph = networkx.DiGraph(networkx.nx_pydot.read_dot(dotfile))
    def node_missing(node):
        import difflib
        close_matches = difflib.get_close_matches(node, graph.nodes(), cutoff=0.7)
        if close_matches:
            print('ERROR: no node "%s" in graph. Close matches:\n  %s' % (node, '\n  '.join(close_matches)))
        sys.exit(1)

    if not fromnode in graph:
        node_missing(fromnode)
    if not tonode in graph:
        node_missing(tonode)
    return networkx.all_simple_paths(graph, source=fromnode, target=tonode)


def find_paths(args):
    path = None
    for path in get_path_networkx(args.dotfile, args.fromnode, args.tonode):
        print(" -> ".join(map(str, path)))
    if not path:
        print("ERROR: no path from %s to %s in graph" % (args.fromnode, args.tonode))
        return 1


def filter_graph(args):
    import fnmatch

    exclude_tasks = []
    if args.exclude_tasks:
        for task in args.exclude_tasks.split(','):
            if not task.startswith('do_'):
                task = 'do_%s' % task
            exclude_tasks.append(task)

    def checkref(strval):
        strval = strval.strip().strip('"')
        target, taskname = strval.rsplit('.', 1)
        if exclude_tasks:
            for extask in exclude_tasks:
                if fnmatch.fnmatch(taskname, extask):
                    return False
        if strval in args.ref or target in args.ref:
            return True
        return False

    with open(args.infile, 'r') as f:
        for line in f:
            line = line.rstrip()
            if line.startswith(('digraph', '}')):
                print(line)
            elif '->' in line:
                linesplit = line.split('->')
                if checkref(linesplit[0]) and checkref(linesplit[1]):
                    print(line)
            elif (not args.no_nodes) and checkref(line.split()[0]):
                print(line)


def main():
    parser = argparse_oe.ArgumentParser(description='Small utility for working with .dot graph files')

    subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>')
    subparsers.required = True

    parser_find_paths = subparsers.add_parser('find-paths',
                                              help='Find all of the paths between two nodes in a dot graph',
                                              description='Finds all of the paths between two nodes in a dot graph')
    parser_find_paths.add_argument('dotfile', help='.dot graph to search in')
    parser_find_paths.add_argument('fromnode', help='starting node name')
    parser_find_paths.add_argument('tonode', help='ending node name')
    parser_find_paths.set_defaults(func=find_paths)

    parser_filter = subparsers.add_parser('filter',
                                           help='Pare down a task graph to contain only the specified references',
                                           description='Pares down a task-depends.dot graph produced by bitbake -g to contain only the specified references')
    parser_filter.add_argument('infile', help='Input file')
    parser_filter.add_argument('ref', nargs='+', help='Reference to include (either recipe/target name or full target.taskname specification)')
    parser_filter.add_argument('-n', '--no-nodes', action='store_true', help='Skip node formatting lines')
    parser_filter.add_argument('-x', '--exclude-tasks', help='Comma-separated list of tasks to exclude (do_ prefix optional, wildcards allowed)')
    parser_filter.set_defaults(func=filter_graph)

    args = parser.parse_args()

    ret = args.func(args)
    return ret


if __name__ == "__main__":
    ret = main()
    sys.exit(ret)
