#!/usr/bin/env python

import sys
import os

from rdflib import Graph, term, RDF
import importlib

from module import Module, ModuleExecution
import datetime
import time

#################################

SM="http://topbraid.org/sparqlmotion#"
DP="http://onto.fel.cvut.cz/ontologies/datapype/"

if ( len(sys.argv) < 2 ):
    print "Provide URI of the Module Instance. Each module instance must contain 'config.ttl' file."
    exit()

moduleDir = os.path.dirname(os.path.realpath(__file__))

moduleToRun=None
pipelineDir=sys.argv[1]
if (len(sys.argv) > 2):
    moduleToRun=sys.argv[2]

modules=Graph()
moduleDirs={}

for moduleDirectory in os.walk("."):
    moduleConfig=moduleDirectory[0]+"/config.ttl"
    if not os.path.isfile(moduleConfig):
        continue
    # print "Processing ", moduleConfig

    moduleGraph = Graph().parse(moduleConfig, format="n3")
    modules = modules + moduleGraph

    for s, p, o in moduleGraph.triples((None, RDF.type, term.URIRef("http://topbraid.org/sparqlmotion#Module"))):
        moduleDirs[s] = moduleDirectory[0].replace("./","")

pipeline = modules + Graph().parse(pipelineDir+"/config.ttl", format="n3")

def runModule(module, pipeline, context):
    instance = context['executedModules'].get(module);
    if not instance:
        moduleClass = pipeline.value(subject=module,predicate=RDF.type)
        moduleClassImplementation = pipeline.value(subject=moduleClass,predicate=term.URIRef(DP+"implementation"))
        moduleName,className = moduleClassImplementation[:moduleClassImplementation.rfind('.')], moduleClassImplementation[moduleClassImplementation.rfind('.')+1:]
        moduleName = moduleDirs[moduleClass]+"."+moduleName
        class_ = getattr(importlib.import_module(moduleName), className)
        instance = class_(module,os.path.abspath(pipelineDir))
        context['executedModules'][module] = instance

    if not instance.execution:
        # get inputs
        inputGraph = Graph();
        for predecessorModule in pipeline.subjects(term.URIRef(SM+"next"), module):
            print "- found predecessor ", predecessorModule
            predecessorInstance = runModule(predecessorModule,pipeline,context)
            if predecessorInstance.outputGraph:
                inputGraph = inputGraph + predecessorInstance.outputGraph
        instance.setInputGraph(inputGraph)
        instance.execution = ModuleExecution(instance,context)
        instance.execution.run();

    return instance

if moduleToRun:
    q = [[term.URIRef(moduleToRun)]]
else:
    qx = """ PREFIX sm: <http://topbraid.org/sparqlmotion#>
             SELECT ?instance
                {
                    ?instance a [<http://onto.fel.cvut.cz/ontologies/datapype/implementation> _:a]
                    FILTER NOT EXISTS { ?instance sm:next [] }.
                }
    """
    q = pipeline.query(qx)

resultGraph = Graph();
executionId=datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d-%H:%M:%S')
context={ "executionId" : executionId, "executedModules" : {}}
instance=None
for res in q:
    print "******** TARGET ******** ", res
    instance = runModule(res[0],pipeline, context)
    if instance.getOutputGraph():
        resultGraph = resultGraph + instance.getOutputGraph()

if instance:
    resultGraph.serialize(format='turtle', destination= instance.execution.e_dir+"/out/output.ttl")
