import asyncio
from utils import ProgressBar
import distribs
import makeclusters
import queue
from tcpip import Message
import os
import dill
from objects import ObjectContainer
import graphs

class Process:
    def __init__(self,loop):
        self._loop = loop
        self._queue = asyncio.Queue(loop = self._loop)
        self._running = False
        self._completed = False
        self._progress = None
        self.name = 'noname'
    async def scan(self,progress):
        while progress._iteration < progress._total:
            await self._queue.put(Message(Message.STRING,progress._display()))
            await asyncio.sleep(1) 
        
    async def start(self):
        self.run()

class ProcessCovar(Process):
    def __init__(self,loop):
        Process.__init__(self,loop)
        self._running = False
        self.name = 'covariances'
    async def run(self):
        self._running = True
        args = distribs.init()
        self._progress = args[-1]._pr
        D = args[-1]
        self._distrib = D        
        await distribs.run(*args)
        self._completed = True
        return 'ok'
     
    def interrupt(self):
        self._distrib._interrupt.set()
        
        
class ProcessClusters(Process):
    def __init__(self,loop):
        Process.__init__(self,loop)
        self._running = False
        self.name = 'clusters'    
    
    async def run(self):
        self._running = True
        args = makeclusters.init_clusters()
        self._clusters = args
        self._progress = args._pr
        await makeclusters.run_clusters(args)
        self.save()
        return 'ok'
    
    def save(self):
        makeclusters.save_clusters(self._clusters)
        self._completed = True
        
    def interrupt(self):
        self._clusters._interrupt.set() 
        
class ProcessRegimes(Process):
    def __init__(self,loop):
        Process.__init__(self,loop)
        self._running = False
        self.name = 'regimes'    
    
    async def run(self):
        self._running = True
        args = makeclusters.init_regimes()
        self._regimes = args
        self._progress = None
        if args is None:
            return 
        ret = await makeclusters.run_regimes(args)
        self.save()
        return ret
    
    def save(self):  
        ObjectContainer.getInstance().set('regimes',self._regimes)
        ObjectContainer.getInstance().save()
        self._completed = True
        
    def interrupt(self):
        pass
 
 
class ProcessFile(Process):
    def __init__(self,loop,args):
        Process.__init__(self,loop)
        self._running = False
        self._fname = args[0]
        self._data = args[1]
        self.name = 'send ' + self._fname
        
    async def run(self):
        self._running = True
        with open(self._fname,'wb') as f:
            f.write(self._data)
            f.flush()
            self._completed = True
        return 'ok'
    
    def interrupt(self):
        pass        
        
class ProcessGraphs(Process):
    
    def __init__(self,loop,args):
        Process.__init__(self,loop)
        self._running = False
        self._func = args[0]
        self._args  = None
        if len(args) > 1:
            self._args = args[1]
        self.name = 'graph ' + self._func
     
      
    async def run(self):
        self._running = True
        g = graphs.init_graph()
        #todo reclalc if not there
        g._clusters = ObjectContainer.getInstance().get('clusters')
        g._regimes = ObjectContainer.getInstance().get('regimes')
        buf = graphs.action(g, self._func, self._args)
        print ('size', len(buf.getvalue()))
        self._completed = True
        return buf
    
    def interrupt(self):
        pass        
         
        
        
        
if __name__=="__main__":
    loop = asyncio.get_event_loop()
    p = ProcessCovar(loop)
    p._running=True
    p._loop.run_until_complete(p.run())