from Ft.Rdf.Drivers import Memory
from Ft.Rdf import Model, Statement
def CreateInfEng():
    from Ft.Rdf.Inference import InferenceEngine
    db = Memory.DbAdapter('kb')
    db.begin()
    kb = Model.Model(db)
    return InferenceEngine.InferenceEngine(kb)

class DummyStatement:
    def __init__(self,s,p,o):
        self.s = s
        self.o = o
        self.p = p
    def execute(self,infEng,context):
        return [(self.s,self.p,self.o)]

class SortStatements:
    def __init__(self,objects):
        self.objects = objects
    def execute(self,infEng,context):
        rt = []
        for o in self.objects:
            rt.append(("S","P",o))
        return rt

def Test(test):
    test.startGroup('Inference Action')
    
    test.startTest('Syntax')
    if 1:
    #try:
        from Ft.Rdf.Inference import InferenceEngine
        from Ft.Rdf.Inference import Common
        from Ft.Rdf.Inference import Action
    #except:
    #    test.error('Error in syntax', 1)
    test.testDone()


    test.startTest('SubjectStatement')
    s1 = DummyStatement("S","P","O")
    a1 = Action.StatementSubject(s1)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)

    test.testResults(["S"],results)

    test.startTest('StatementPredicate')
    s1 = DummyStatement("S","P","O")
    a1 = Action.StatementPredicate(s1)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)

    test.testResults(["P"],results)

    test.startTest('StatementObject')
    s1 = DummyStatement("S","P","O")
    a1 = Action.StatementObject(s1)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)

    test.testResults(["O"],results)

    test.startTest('Paths')

    #Add the path atatements
    infeng = CreateInfEng()

    statements = map(lambda x, s=Statement.Statement:
                     apply(s, x),
                     [("A","s1","B"),
                      ("B","s2","C"),
                      ("C","s3","D"),
                      ("D","s4","E"),
                      ("A","s5","D"),
                      ("A","s6","F"),
                      ("F","s7","E"),
                      ]
                     )
    infeng.workspace.add(statements)

    #There are 3 paths from A to E
    start = Common.StringLiteralArgument("arg1","A")
    end = Common.StringLiteralArgument("arg1","E")
    #Note exclude s7
    predicates = Common.StringListLiteralArgument("arg2",['s1','s2','s3','s4','s5','s6'])

    a = Action.PathsAction(start,end,predicates)

    context = Common.Context()
    result = a.execute(infeng,context)


    test.testResults([[[('A', 's1', 'B'), ('B', 's2', 'C'), ('C', 's3', 'D'), ('D', 's4', 'E')], [('A', 's5', 'D'), ('D', 's4', 'E')]]],result)


    test.startTest('Reverse Paths')

    #Add the path atatements
    infeng = CreateInfEng()

    infeng.workspace.add(statements)

    #There are 3 paths from A to E
    start = Common.StringLiteralArgument("arg1","E")
    end = Common.StringLiteralArgument("arg1","A")
    #Note exclude s7
    predicates = Common.StringListLiteralArgument("arg2",['s1','s2','s3','s4','s5','s6'])

    a = Action.ReversePathsAction(start,end,predicates)

    context = Common.Context()
    result = a.execute(infeng,context)
    test.testResults([[[('D', 's4', 'E'), ('C', 's3', 'D'), ('B', 's2', 'C'), ('A', 's1', 'B')], [('D', 's4', 'E'), ('A', 's5', 'D')]]],result)


    test.startTest('Index Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3','4','5','6'])
    a1 = Action.IndexAction(s,4)
    infeng = CreateInfEng()
    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["5"],results)

    test.startTest('Reverse Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3','4','5','6'])
    a1 = Action.ReverseAction(s)
    infeng = CreateInfEng()
    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["6",'5','4','3','2','1'],results)

    test.startTest('Slice Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3','4','5','6'])
    a1 = Action.SliceAction(s,2,4)
    infeng = CreateInfEng()
    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["3",'4'],results)

    test.startTest('Unique Action')
    s = Common.StringListLiteralArgument("arg2",['1','1','2'])
    a1 = Action.UniqueAction(s)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["1",'2'],results)

    test.startTest('Intersection Action')
    s = Common.StringListLiteralArgument("arg2",['1','2'])
    s1 = Common.StringListLiteralArgument("arg3",['2','3'])
    a1 = Action.IntersectionAction(s,s1)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["2"],results)

    test.startTest('Union Action')
    s = Common.StringListLiteralArgument("arg2",['1','2'])
    s1 = Common.StringListLiteralArgument("arg3",['2','3'])
    a1 = Action.UnionAction(s,s1)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["1",'2','3'],results)

    test.startTest('Sum Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3'])
    a1 = Action.SumAction(s)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["6.0"],results)

    test.startTest('Count Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3'])
    a1 = Action.CountAction(s)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["3"],results)

    test.startTest('Average Action')
    s = Common.StringListLiteralArgument("arg2",['1','2','3'])
    a1 = Action.AverageAction(s)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults(["2.0"],results)

    test.startTest('Sort Action (NUMBER')
    s = SortStatements(["3","2","1"])
    a1 = Action.SortAction(s,Action.SortType.NUMBER_SORT)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults([('S', 'P', '1'), ('S', 'P', '2'), ('S', 'P', '3')],results)


    test.startTest('Sort Action (STRING)')
    s = SortStatements(["C","B","A"])
    a1 = Action.SortAction(s,Action.SortType.STRING_SORT)

    infeng = CreateInfEng()

    context = Common.Context()
    results = a1.execute(infeng,context)
    test.testResults([('S', 'P', 'A'), ('S', 'P', 'B'), ('S', 'P', 'C')],results)

    test.startTest('Set Variable')
    v = Common.VariableReferenceArgument("X")
    s = Common.StringListLiteralArgument("arg2",['1','2','3'])
    a1 = Action.VariableSetAction("X",s)

    infeng = CreateInfEng()

    context = Common.Context()
    a1.execute(infeng,context)

    test.testResults(['1','2','3'],v.execute(infeng,context))

    test.testDone()
    test.groupDone()


if __name__ == '__main__':
    import sys
    from Ft.Lib import TestSuite

    testmgr = TestSuite.TestSuite()
    ret_val = Test(testmgr)
    sys.exit(ret_val)

