#! /usr/bin/env python
import inspect
import os
from abjad import abjad_configuration
from abjad.tools import systemtools
from abjad.tools.abctools import AbjadObject
from abjad.tools.documentationtools import ClassCrawler
from abjad.tools.documentationtools import InheritanceGraph
from scoremanager.idetools.Controller import Controller


def shorten_class_name(abjad_class):
    parts = abjad_class.__module__.split('.')[-2:]
    return '{}.{}'.format(parts[0], parts[1])


def find_inconsistencies():
    tools_path = os.path.abspath('.')
    abjad_classes = ClassCrawler(tools_path)()
    graph = InheritanceGraph(
        addresses=abjad_classes, 
        root_addresses=[AbjadObject, Controller],
        )
    bad_arcs = []
    for parent, children in graph.parent_children_mapping.iteritems():
        parent_attrs = inspect.classify_class_attrs(parent)
        parent_slots_def = [x for x in parent_attrs
            if x.name == '__slots__'][0].defining_class
        for child in children:
            print child
            child_attrs = inspect.classify_class_attrs(child)
            child_slots_def = [x for x in child_attrs
                if x.name == '__slots__'][0].defining_class
            if child_slots_def == child and parent_slots_def != parent:
                bad_arcs.append((parent, child))
    if bad_arcs:
        print '%d bad slots relationships found:' % len(bad_arcs)
        generator = sorted(
            bad_arcs, 
            key=lambda x: (x[0].__module__, x[1].__module__)
            )
        for parent, child in generator:
            print '\t{} -> {}'.format(
                shorten_class_name(parent), 
                shorten_class_name(child),
                parent,
                child,
                )
    else:
        print 'No bad slots relationships found.'
    return graph


if __name__ == '__main__':
    systemtools.IOManager.clear_terminal()
    graph = find_inconsistencies()
    print