#!/usr/bin/env python3
#
# Copyright (C) 2018 Wind River Systems, Inc.
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import sys
import argparse
import logging
import re

class Dot(object):
    def __init__(self):
        parser = argparse.ArgumentParser(
            description="Analyse recipe-depends.dot generated by bitbake -g",
            epilog="Use %(prog)s --help to get help")
        parser.add_argument("dotfile",
            help = "Specify the dotfile", nargs = 1, action='store', default='')
        parser.add_argument("-k", "--key",
            help = "Specify the key, e.g., recipe name",
            action="store", default='')
        parser.add_argument("-d", "--depends",
            help = "Print the key's dependencies",
            action="store_true", default=False)
        parser.add_argument("-w", "--why",
            help = "Print why the key is built",
            action="store_true", default=False)
        parser.add_argument("-r", "--remove",
            help = "Remove duplicated dependencies to reduce the size of the dot files."
                    " For example, A->B, B->C, A->C, then A->C can be removed.",
            action="store_true", default=False)

        self.args = parser.parse_args()

        if len(sys.argv) != 3 and len(sys.argv) < 5:
            print('ERROR: Not enough args, see --help for usage')

    @staticmethod
    def insert_dep_chain(chain, rdeps, alldeps):
        """
        insert elements to chain from rdeps, according to alldeps
        """
        # chain should at least contain one element
        if len(chain) == 0:
            raise

        inserted_elements = []
        for rdep in rdeps:
            if rdep in chain:
                continue
            else:
                for i in range(0, len(chain)-1):
                    if chain[i] in alldeps[rdep] and rdep in alldeps[chain[i+1]]:
                        chain.insert(i+1, rdep)
                        inserted_elements.append(rdep)
                        break
                if chain[-1] in alldeps[rdep] and rdep not in chain:
                    chain.append(rdep)
                    inserted_elements.append(rdep)
        return inserted_elements

    @staticmethod
    def print_dep_chains(key, rdeps, alldeps):
        rlist = rdeps.copy()
        chain = []
        removed_rdeps = [] # hold rdeps removed from rlist

        chain.append(key)
        while (len(rlist) != 0):
            # insert chain from rlist
            inserted_elements = Dot.insert_dep_chain(chain, rlist, alldeps)
            if not inserted_elements:
                if chain[-1] in rlist:
                    rlist.remove(chain[-1])
                    removed_rdeps.append(chain[-1])
                chain.pop()
                continue
            else:
                # insert chain from removed_rdeps
                Dot.insert_dep_chain(chain, removed_rdeps, alldeps)
                print(' -> '.join(list(reversed(chain))))

    def main(self):
        #print(self.args.dotfile[0])
        # The format is {key: depends}
        depends = {}
        with open(self.args.dotfile[0], 'r') as f:
            for line in f.readlines():
                if ' -> ' not in line:
                    continue
                line_no_quotes = line.replace('"', '')
                m = re.match("(.*) -> (.*)", line_no_quotes)
                if not m:
                    print('WARNING: Found unexpected line: %s' % line)
                    continue
                key = m.group(1)
                if key == "meta-world-pkgdata":
                    continue
                dep = m.group(2)
                if key in depends:
                    if not key in depends[key]:
                        depends[key].add(dep)
                    else:
                        print('WARNING: Fonud duplicated line: %s' % line)
                else:
                    depends[key] = set()
                    depends[key].add(dep)

        if self.args.remove:
            reduced_depends = {}
            for k, deps in depends.items():
                child_deps = set()
                added = set()
                # Both direct and indirect depends are already in the dict, so
                # we don't have to do this recursively.
                for dep in deps:
                    if dep in depends:
                        child_deps |= depends[dep]

                reduced_depends[k] = deps - child_deps
                outfile= '%s-reduced%s' % (self.args.dotfile[0][:-4], self.args.dotfile[0][-4:])
            with open(outfile, 'w') as f:
                print('Saving reduced dot file to %s' % outfile)
                f.write('digraph depends {\n')
                for k, v in reduced_depends.items():
                    for dep in v:
                        f.write('"%s" -> "%s"\n' % (k, dep))
                f.write('}\n')
            sys.exit(0)

        if self.args.key not in depends:
            print("ERROR: Can't find key %s in %s" % (self.args.key, self.args.dotfile[0]))
            sys.exit(1)

        if self.args.depends:
            if self.args.key in depends:
                print('Depends: %s' % ' '.join(depends[self.args.key]))

        reverse_deps = []
        if self.args.why:
            for k, v in depends.items():
                if self.args.key in v and not k in reverse_deps:
                    reverse_deps.append(k)
            print('Because: %s' % ' '.join(reverse_deps))
            Dot.print_dep_chains(self.args.key, reverse_deps, depends)

if __name__ == "__main__":
    try:
        dot = Dot()
        ret = dot.main()
    except Exception as esc:
        ret = 1
        import traceback
        traceback.print_exc()
    sys.exit(ret)
