##@package iginterface
# Instance generator interface.
#@author Sebastien MATHIEU

import time, sys, threading, queue, subprocess,traceback,os
import asyncio,websockets
import xml.etree.ElementTree as ElementTree

from .job import Job
from .log import log

## Computation thread of the instance generator.
def computationThread(job):	
	try:
		job.status=Job.RUNNING
		
		xmlContent=job.args[1]
		instancesFolder=job.args[0]
		
		# Get the hash
		root=ElementTree.fromstring(xmlContent)
		tree=ElementTree.ElementTree(root)
		hash=root.find('hash').text
		directory='%s/%s'%(instancesFolder,hash)
		if not os.path.exists(directory):
			os.makedirs(directory)
		
		# Write the xml file
		xmlDataFile='%s/%s.xml'%(directory,hash)
		tree.write(xmlDataFile)
		
		# Launch the generation
		cmd=['python3', 'main.py', '../%s/%s/%s.xml'%(instancesFolder,hash,hash), '../%s'%instancesFolder]
		job.process = subprocess.Popen(cmd, cwd='instanceGenerator', stdout=subprocess.PIPE, stderr=subprocess.PIPE) # TODO remove pipes
		log("Instance generation of %s with the cmd \"%s\" started"%(hash," ".join(cmd)))
		returnCode=job.process.wait()
		log("Instance generation process of %s finished"%hash)
		if job.status != Job.ERROR:
			# Get the process outputs
			stdout, stderr = job.process.communicate()
			stderr=stderr.decode('latin-1').strip()
			stdout=stdout.decode('latin-1').strip() # Clean text answer
			if stderr != "":
				log("Stderr:\n%s"%stderr)
			
			# Get the status tag of the xml document
			statusTag=root.find('status')
			if statusTag is None:
				statusTag=ElementTree.Element('status')
				root.append(statusTag)
			
			# Notifies the completion of the job
			if returnCode == 0:
				job.result=stdout
				job.status=Job.COMPLETED
				statusTag.text="generated"
			else:
				job.result=stderr
				job.status=Job.ERROR
				statusTag.text="error instance generation"
			tree.write(xmlDataFile)
		else:
			job.result=Exception("Job killed !")
			
	except Exception as e:
		job.status=Job.ERROR
		job.result=e
		log(traceback.format_exc())
	finally:
		#TODO Clean the mess if aborted
		job.finished.release()
	
## Interact with the user and with the instance generator module.
# @param client Client we are interacting with.
@asyncio.coroutine
def interact(client):
	# Agree to receive the instance parameters and waits
	yield from client.socket.send("ok instance generation request")
	xmlParameters=yield from client.socket.recv()	
	if xmlParameters is None:
		return
	yield from client.socket.send("ok instance received")
	client.log("\n"+xmlParameters)

	# Start the instance generation thread
	job=Job([client.instancesFolder,xmlParameters])
	thread=threading.Thread(target=computationThread,args=[job])
	thread.daemon=True
	thread.start()
	
	# Get the hash
	root=ElementTree.fromstring(xmlParameters)	
	hash=root.find('hash').text
		
	# Polling of the client until the job is complete
	while True:
		message = yield from client.socket.recv()
		if message is None or message.strip().lower()=="terminate":
			# Kill thread if running
			if job.status==Job.RUNNING or job.status==Job.WAITING:
				client.log("Terminate request \"%s\""%hash)
				job.status=Job.ABORTED
				if job.process is not None:
					job.process.terminate()
			break
		elif message.strip().lower() == "ready?":
			# Check status
			if job.finished.locked():
				if job.status==Job.RUNNING:
					yield from client.socket.send("ok running \"%s\""%hash)
				else:
					yield from client.socket.send("ok waiting \"%s\""%hash)
			else:
				thread.join()
				if job.status==Job.COMPLETED:
					yield from client.socket.send("ok instance generated \"%s\""%hash)
				else:
					raise Exception(job.result)
				break
		else:
			yield from client.handleMessage(message)

	
8a9ec78fea937dd84354e2931c41d1f5f125db18
<mask token>

<mask token>


@asyncio.coroutine
def interact(client):
    yield from client.socket.send('ok instance generation request')
    xmlParameters = yield from client.socket.recv()
    if xmlParameters is None:
        return
    yield from client.socket.send('ok instance received')
    client.log('\n' + xmlParameters)
    job = Job([client.instancesFolder, xmlParameters])
    thread = threading.Thread(target=computationThread, args=[job])
    thread.daemon = True
    thread.start()
    root = ElementTree.fromstring(xmlParameters)
    hash = root.find('hash').text
    while True:
        message = yield from client.socket.recv()
        if message is None or message.strip().lower() == 'terminate':
            if job.status == Job.RUNNING or job.status == Job.WAITING:
                client.log('Terminate request "%s"' % hash)
                job.status = Job.ABORTED
                if job.process is not None:
                    job.process.terminate()
            break
        elif message.strip().lower() == 'ready?':
            if job.finished.locked():
                if job.status == Job.RUNNING:
                    yield from client.socket.send('ok running "%s"' % hash)
                else:
                    yield from client.socket.send('ok waiting "%s"' % hash)
            else:
                thread.join()
                if job.status == Job.COMPLETED:
                    yield from client.socket.send(
                        'ok instance generated "%s"' % hash)
                else:
                    raise Exception(job.result)
                break
        else:
            yield from client.handleMessage(message)

<mask token>


def computationThread(job):
    try:
        job.status = Job.RUNNING
        xmlContent = job.args[1]
        instancesFolder = job.args[0]
        root = ElementTree.fromstring(xmlContent)
        tree = ElementTree.ElementTree(root)
        hash = root.find('hash').text
        directory = '%s/%s' % (instancesFolder, hash)
        if not os.path.exists(directory):
            os.makedirs(directory)
        xmlDataFile = '%s/%s.xml' % (directory, hash)
        tree.write(xmlDataFile)
        cmd = ['python3', 'main.py', '../%s/%s/%s.xml' % (instancesFolder,
            hash, hash), '../%s' % instancesFolder]
        job.process = subprocess.Popen(cmd, cwd='instanceGenerator', stdout
            =subprocess.PIPE, stderr=subprocess.PIPE)
        log('Instance generation of %s with the cmd "%s" started' % (hash,
            ' '.join(cmd)))
        returnCode = job.process.wait()
        log('Instance generation process of %s finished' % hash)
        if job.status != Job.ERROR:
            stdout, stderr = job.process.communicate()
            stderr = stderr.decode('latin-1').strip()
            stdout = stdout.decode('latin-1').strip()
            if stderr != '':
                log('Stderr:\n%s' % stderr)
            statusTag = root.find('status')
            if statusTag is None:
                statusTag = ElementTree.Element('status')
                root.append(statusTag)
            if returnCode == 0:
                job.result = stdout
                job.status = Job.COMPLETED
                statusTag.text = 'generated'
            else:
                job.result = stderr
                job.status = Job.ERROR
                statusTag.text = 'error instance generation'
            tree.write(xmlDataFile)
        else:
            job.result = Exception('Job killed !')
    except Exception as e:
        job.status = Job.ERROR
        job.result = e
        log(traceback.format_exc())
    finally:
        job.finished.release()


@asyncio.coroutine
def interact(client):
    yield from client.socket.send('ok instance generation request')
    xmlParameters = yield from client.socket.recv()
    if xmlParameters is None:
        return
    yield from client.socket.send('ok instance received')
    client.log('\n' + xmlParameters)
    job = Job([client.instancesFolder, xmlParameters])
    thread = threading.Thread(target=computationThread, args=[job])
    thread.daemon = True
    thread.start()
    root = ElementTree.fromstring(xmlParameters)
    hash = root.find('hash').text
    while True:
        message = yield from client.socket.recv()
        if message is None or message.strip().lower() == 'terminate':
            if job.status == Job.RUNNING or job.status == Job.WAITING:
                client.log('Terminate request "%s"' % hash)
                job.status = Job.ABORTED
                if job.process is not None:
                    job.process.terminate()
            break
        elif message.strip().lower() == 'ready?':
            if job.finished.locked():
                if job.status == Job.RUNNING:
                    yield from client.socket.send('ok running "%s"' % hash)
                else:
                    yield from client.socket.send('ok waiting "%s"' % hash)
            else:
                thread.join()
                if job.status == Job.COMPLETED:
                    yield from client.socket.send(
                        'ok instance generated "%s"' % hash)
                else:
                    raise Exception(job.result)
                break
        else:
            yield from client.handleMessage(message)

import time, sys, threading, queue, subprocess, traceback, os
import asyncio, websockets
import xml.etree.ElementTree as ElementTree
from .job import Job
from .log import log


def computationThread(job):
    try:
        job.status = Job.RUNNING
        xmlContent = job.args[1]
        instancesFolder = job.args[0]
        root = ElementTree.fromstring(xmlContent)
        tree = ElementTree.ElementTree(root)
        hash = root.find('hash').text
        directory = '%s/%s' % (instancesFolder, hash)
        if not os.path.exists(directory):
            os.makedirs(directory)
        xmlDataFile = '%s/%s.xml' % (directory, hash)
        tree.write(xmlDataFile)
        cmd = ['python3', 'main.py', '../%s/%s/%s.xml' % (instancesFolder,
            hash, hash), '../%s' % instancesFolder]
        job.process = subprocess.Popen(cmd, cwd='instanceGenerator', stdout
            =subprocess.PIPE, stderr=subprocess.PIPE)
        log('Instance generation of %s with the cmd "%s" started' % (hash,
            ' '.join(cmd)))
        returnCode = job.process.wait()
        log('Instance generation process of %s finished' % hash)
        if job.status != Job.ERROR:
            stdout, stderr = job.process.communicate()
            stderr = stderr.decode('latin-1').strip()
            stdout = stdout.decode('latin-1').strip()
            if stderr != '':
                log('Stderr:\n%s' % stderr)
            statusTag = root.find('status')
            if statusTag is None:
                statusTag = ElementTree.Element('status')
                root.append(statusTag)
            if returnCode == 0:
                job.result = stdout
                job.status = Job.COMPLETED
                statusTag.text = 'generated'
            else:
                job.result = stderr
                job.status = Job.ERROR
                statusTag.text = 'error instance generation'
            tree.write(xmlDataFile)
        else:
            job.result = Exception('Job killed !')
    except Exception as e:
        job.status = Job.ERROR
        job.result = e
        log(traceback.format_exc())
    finally:
        job.finished.release()


@asyncio.coroutine
def interact(client):
    yield from client.socket.send('ok instance generation request')
    xmlParameters = yield from client.socket.recv()
    if xmlParameters is None:
        return
    yield from client.socket.send('ok instance received')
    client.log('\n' + xmlParameters)
    job = Job([client.instancesFolder, xmlParameters])
    thread = threading.Thread(target=computationThread, args=[job])
    thread.daemon = True
    thread.start()
    root = ElementTree.fromstring(xmlParameters)
    hash = root.find('hash').text
    while True:
        message = yield from client.socket.recv()
        if message is None or message.strip().lower() == 'terminate':
            if job.status == Job.RUNNING or job.status == Job.WAITING:
                client.log('Terminate request "%s"' % hash)
                job.status = Job.ABORTED
                if job.process is not None:
                    job.process.terminate()
            break
        elif message.strip().lower() == 'ready?':
            if job.finished.locked():
                if job.status == Job.RUNNING:
                    yield from client.socket.send('ok running "%s"' % hash)
                else:
                    yield from client.socket.send('ok waiting "%s"' % hash)
            else:
                thread.join()
                if job.status == Job.COMPLETED:
                    yield from client.socket.send(
                        'ok instance generated "%s"' % hash)
                else:
                    raise Exception(job.result)
                break
        else:
            yield from client.handleMessage(message)

##@package iginterface
# Instance generator interface.
#@author Sebastien MATHIEU

import time, sys, threading, queue, subprocess,traceback,os
import asyncio,websockets
import xml.etree.ElementTree as ElementTree

from .job import Job
from .log import log

## Computation thread of the instance generator.
def computationThread(job):	
	try:
		job.status=Job.RUNNING
		
		xmlContent=job.args[1]
		instancesFolder=job.args[0]
		
		# Get the hash
		root=ElementTree.fromstring(xmlContent)
		tree=ElementTree.ElementTree(root)
		hash=root.find('hash').text
		directory='%s/%s'%(instancesFolder,hash)
		if not os.path.exists(directory):
			os.makedirs(directory)
		
		# Write the xml file
		xmlDataFile='%s/%s.xml'%(directory,hash)
		tree.write(xmlDataFile)
		
		# Launch the generation
		cmd=['python3', 'main.py', '../%s/%s/%s.xml'%(instancesFolder,hash,hash), '../%s'%instancesFolder]
		job.process = subprocess.Popen(cmd, cwd='instanceGenerator', stdout=subprocess.PIPE, stderr=subprocess.PIPE) # TODO remove pipes
		log("Instance generation of %s with the cmd \"%s\" started"%(hash," ".join(cmd)))
		returnCode=job.process.wait()
		log("Instance generation process of %s finished"%hash)
		if job.status != Job.ERROR:
			# Get the process outputs
			stdout, stderr = job.process.communicate()
			stderr=stderr.decode('latin-1').strip()
			stdout=stdout.decode('latin-1').strip() # Clean text answer
			if stderr != "":
				log("Stderr:\n%s"%stderr)
			
			# Get the status tag of the xml document
			statusTag=root.find('status')
			if statusTag is None:
				statusTag=ElementTree.Element('status')
				root.append(statusTag)
			
			# Notifies the completion of the job
			if returnCode == 0:
				job.result=stdout
				job.status=Job.COMPLETED
				statusTag.text="generated"
			else:
				job.result=stderr
				job.status=Job.ERROR
				statusTag.text="error instance generation"
			tree.write(xmlDataFile)
		else:
			job.result=Exception("Job killed !")
			
	except Exception as e:
		job.status=Job.ERROR
		job.result=e
		log(traceback.format_exc())
	finally:
		#TODO Clean the mess if aborted
		job.finished.release()
	
## Interact with the user and with the instance generator module.
# @param client Client we are interacting with.
@asyncio.coroutine
def interact(client):
	# Agree to receive the instance parameters and waits
	yield from client.socket.send("ok instance generation request")
	xmlParameters=yield from client.socket.recv()	
	if xmlParameters is None:
		return
	yield from client.socket.send("ok instance received")
	client.log("\n"+xmlParameters)

	# Start the instance generation thread
	job=Job([client.instancesFolder,xmlParameters])
	thread=threading.Thread(target=computationThread,args=[job])
	thread.daemon=True
	thread.start()
	
	# Get the hash
	root=ElementTree.fromstring(xmlParameters)	
	hash=root.find('hash').text
		
	# Polling of the client until the job is complete
	while True:
		message = yield from client.socket.recv()
		if message is None or message.strip().lower()=="terminate":
			# Kill thread if running
			if job.status==Job.RUNNING or job.status==Job.WAITING:
				client.log("Terminate request \"%s\""%hash)
				job.status=Job.ABORTED
				if job.process is not None:
					job.process.terminate()
			break
		elif message.strip().lower() == "ready?":
			# Check status
			if job.finished.locked():
				if job.status==Job.RUNNING:
					yield from client.socket.send("ok running \"%s\""%hash)
				else:
					yield from client.socket.send("ok waiting \"%s\""%hash)
			else:
				thread.join()
				if job.status==Job.COMPLETED:
					yield from client.socket.send("ok instance generated \"%s\""%hash)
				else:
					raise Exception(job.result)
				break
		else:
			yield from client.handleMessage(message)

	