"""
	This file encapsulates a class that is intended to perform learning
"""
from __future__ import division
import numpy as np
from sklearn import linear_model
from threading import Thread,RLock
from utils.transport import *
from utils.ml import AnomalyDetection,ML
from utils.params import PARAMS
import time
class BaseLearner(Thread):
	def __init__(self,lock) :
		Thread.__init__(self)
		path = PARAMS['path']
		self.name = self.__class__.__name__.lower()
		self.rclass= None
		self.wclass= None
		self.rw_args=None
		if os.path.exists(path) :
			f = open(path)
			self.config = json.loads(f.read())
			f.close()
			self.rclass	= self.config['store']['class']['read']
			self.wclass	= self.config['store']['class']['write']		
			self.rw_args	= self.config['store']['args']

		else:
			self.config = None
		self.lock = lock
		self.factory 	= DataSourceFactory()
		self.quit	= False
	"""
		This function is designed to stop processing gracefully
		
	"""
	def stop(self):
		self.quit = True
		
		
"""
	This class is intended to apply anomaly detection to various areas of learning
	The areas of learning that will be skipped are :
	['_id','_rev','learn'] ... 
	
	@TODO:
		- Find a way to perform dimensionality reduction if need be
"""
class Anomalies(BaseLearner) :
	def __init__(self,lock):		
		BaseLearner.__init__(self,lock)
		if self.config :
			#
			# Initializing data store & factory class
			#
			self.id		= self.config['id']
			self.apps	= self.config['procs'] if 'procs' in self.config else []
			self.rclass	= self.config['store']['class']['read']
			self.wclass	= self.config['store']['class']['write']		
			self.rw_args	= self.config['store']['args']
			# self.factory 	= DataSourceFactory()
			self.quit	= False
			# self.lock 	= lock
	def format(self,stream):
		pass
	def stop(self):
		self.quit = True
            
	def run(self):
		DELAY = self.config['delay'] * 60
		reader 	= self.factory.instance(type=self.rclass,args=self.rw_args)
		data	= reader.read()
		key	= 'apps@'+self.id
		if key in data:
			rdata	= data[key]
			features = ['memory_usage','cpu_usage']
			yo = {"1":["running"],"name":"status"}				
			while self.quit == False :
				print ' *** ',self.name, ' ' , str(datetime.today())
				for app in self.apps:
					print '\t',app,str(datetime.today()),' ** ',app
					logs = ML.Filter('label',app,rdata)
					
					if logs :
						handler = AnomalyDetection()
						value 	= handler.learn(logs,'label',app,features,yo)
						if value is not None:
							value = dict(value,**{"features":features})
							value = dict({"id":self.id},**value)
							#r[id][app] = value
							self.lock.acquire()
							writer = self.factory.instance(type=self.wclass,args=self.rw_args)
							writer.write(label='learn',row=value)
							self.lock.release()
				#
				if 'MONITOR_CONFIG_PATH' in os.environ :
					break
				time.sleep(DELAY)
		print ' *** Exiting ',self.name.replace('a','A')

				
		
"""
	Let's estimate how many files we will have for a given date
	y = ax + b with y: number files, x: date, y: Number of files
"""		
class Regression(BaseLearner):
	def __init__(self,lock):
		BaseLearner.__init__(self,lock)
		self.folders 	= self.config['folders']
		self.id 	= self.config['id']
	def run(self):
		DELAY = self.config['delay'] * 60
		reader 	= self.factory.instance(type=self.rclass,args=self.rw_args)
		data	= reader.read()
		if 'folders' in data :
			data = ML.Filter('id',self.id,data['folders'])
			xo  	= ML.Extract(['date'],data)
			yo	= ML.Extract(['count'],data)
			
			
			pass
			# print np.var(xo,yo)

			
		


if __name__ == '__main__' :
	lock = RLock()
	thread = Anomalies(lock)
	thread.start()