import unittest
import path
import sys
from cStringIO import StringIO

from pynto import cgraph, log

debug_log = None

class TestItem:

    def __init__ (self, value):
        self.value = value
        self.cgraph_index = None
        pass

    def set_cgraph_index (self, idx):
        self.cgraph_index = idx
        pass

    def get_cgraph_index (self):
        return self.cgraph_index

    def __str__ (self):
        return str (self.value)

    def __cmp__ (self, other):
        return cmp (self.value, other.value)

    pass

class TestCGraph (unittest.TestCase):

    def _run_script (self,
                     cgraph,
                     numitems,
                     cpairs,
                     cresults,
                     debug_log):

        # Convert cpairs and cresults to indices
        items = map (TestItem, range (numitems))
        
        for a, b in cpairs:
            if debug_log: debug_log.low ("MAKE_CONFLICT: %d, %d" % (a,b))
            cgraph.make_conflict (items[a], items[b])
            pass
        
        for a, conflicts in cresults.items():
            conflicts = map (lambda x: items[x], conflicts)
            conflicts.sort ()
            conflicting = list (cgraph.conflicting_items (items[a]))
            conflicting.sort ()

            if conflicts != conflicting:
                errorstring = StringIO ()
                errorstring.write ("Conflict map for %s is wrong: Ref" % a)
                for i in conflicts: errorstring.write (" %s" % i)
                errorstring.write (" Actual")
                for i in conflicting: errorstring.write (" %s" % i)
                self.assertEqual (0, 1, errorstring.getvalue())
                pass
            pass
        pass

    def new_cgraph (self):

        return cgraph.ConflictGraph (TestItem.get_cgraph_index,
                                     TestItem.set_cgraph_index,
                                     debug_log,
                                     '')

    def testLadder (self):

        """ Tests a straightforward ladder sequence """

        graph = self.new_cgraph ()

        if debug_log: ind = debug_log.indent ('testLadder')

        self._run_script (graph,
                          6,
                          ( (0, 1),
                            (1, 2),
                            (2, 3),
                            (3, 4),
                            (4, 5),
                            (5, 0) ),
                          { 0:(1, 5),
                            1:(0,2),
                            2:(1,3),
                            3:(2,4),
                            4:(3,5),
                            5:(0,4) },
                          debug_log)
        return

    pass

def add_tests (suite):
    for testname in dir (TestCGraph):
        if testname.startswith ('test'):
            suite.addTest (TestCGraph(testname))
            pass
        pass
    return

if __name__ == "__main__":
    
    if "--debug-mode" in sys.argv:
        sys.argv.remove ("--debug-mode")
        debug_log = log.Log (sys.stderr)
        debug_log.set_level (log.MINUTIA)
        pass

    if "--pdb" in sys.argv:
        sys.argv.remove ("--pdb")
        pdb.runcall (unittest.main)
    else:
        unittest.main ()
        pass

