# -*- coding: utf-8 -*-
from __future__ import division
from .__load__ import *
from .snowboy import snowboydecoder
# 耳朵，聆听者
class Ear(object):

	def init(self, robot):
		# vecan机器人
		self.robot = robot
		# 勿扰模式控制 勿扰模式关闭
		self.bother = False
		# snowboy detector
		self.detector = None
		# 中断控制
		self.interrupted = False
		return self

	# 语音唤醒模式
	def wait(self):
		self.robot.logger.info(self.log('唤醒模式：喊我名字叫醒我吧，我听着呢'))
		if self.detector is not None:
			self.detector.terminate()

		self.getConfig()
		self.detector = snowboydecoder.HotwordDetector(self.config['models'], sensitivity=self.config['sensitivity'], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'],robot=self.robot)
		# main loop
		#try:
		self.detector.start(detected_callback=self.config['callbacks'],
								audio_recorder_callback=self.recorderCallback,
								interrupt_check=self.interruptCallback,
								silent_count_threshold=int(self.config['silent_threshold']),
								recording_timeout=int(self.config['recording_timeout']) * 4,
								sleep_time=0.03)
		self.detector.terminate()
		#except Exception as e:
			#self.robot.logger.critical(self.log('离线唤醒机制初始化失败：{}'.format(e)))

	# listen
	def listen(self, silent=False):
		self.robot.logger.info(self.log('聆听模式：和我直接对话吧'))
		try:
			if not silent:
				time.sleep(1)
				self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
			listener = snowboydecoder.ActiveListener([self.robot.data + self.config['hotword']], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
			voice = listener.listen(
				silent_count_threshold=int(self.config['silent_threshold']),
				recording_timeout=int(self.config['recording_timeout']) * 4
			)
			if not silent:
				self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
			if voice:
				query = self.robot.tool['asr'].asr(voice)
				File.remove(voice)
				return query
		except Exception as e:			
			Demeter.logger.error(e)
			return ''

	# snowboy配置，后续改成从数据库读取
	def getConfig(self):
		self.config = Demeter.config['snowboy']
		if self.config['hotword_switch'] == True:
			self.config['models'] = [
				self.robot.data + self.config['hotword'],
				self.robot.data + self.config['on_hotword'],
				self.robot.data + self.config['off_hotword']
			]

			self.config['callbacks'] = [
				self.detectedCallback,
				self.onHotwordCallback,
				self.offHotwordCallback
			]
		else:
			self.config['models'] = self.robot.data + self.config['hotword']
			self.config['callbacks'] = self.detectedCallback

	# close
	def close(self):
		self.interrupted = True

	# callback
	def detectedCallback(self):
		if not self.isProperTime():
			self.robot.logger.warning(self.log('勿扰模式开启中'))
			return
		if self.robot.isRecording:
			self.robot.logger.warning(self.log('正在录音中，跳过'))
			return
		self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
		self.robot.logger.info(self.log('开始录音'))
		self.robot.stop()
		self.robot.isRecording = True

	def recorderCallback(self, fp, callback=None):
		self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
		self.robot.logger.info(self.log('结束录音'))
		self.robot.isRecording = False
		if self.robot.profiling:
			self.robot.logger.info(self.log('性能调试已打开'))
			pr = cProfile.Profile()
			pr.enable()
			self.recorder(fp, callback)
			pr.disable()
			s = io.StringIO()
			sortby = 'cumulative'
			ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
			ps.print_stats()
			print(s.getvalue())
		else:
			self.recorder(fp, callback)

	def recorder(self, fp, callback=None, onSay=None):
		try:
			self.robot.stop()
			query = self.robot.tool['asr'].asr(fp)
			File.remove(fp)
			self.robot.brain.think(query, callback, onSay)
		except Exception as e:
			self.robot.logger.critical(self.log(e))
			clean()

	def onHotwordCallback(self):
		if self.config['hotword_switch'] == True:
			self.bother = True
			self.robot.mouth.speek(self.robot.data + 'off.wav')
			self.robot.logger.info(self.log('勿扰模式打开'))

	def offHotwordCallback(self):
		if self.config['hotword_switch'] == True:
			self.bother = False
			self.robot.mouth.speek(self.robot.data + 'on.wav')
			self.robot.logger.info(self.log('勿扰模式关闭'))

	def interruptCallback(self):
		return self.interrupted

	def isProperTime(self):
		if self.bother == True:
			return False
		if 'bother_enable' not in self.config:
			return True
		if self.config['bother_enable'] == False:
			return True
		if 'bother_since' not in self.config or 'bother_till' not in self.config:
			return True
		since = int(self.config['bother_since'])
		till = int(self.config['bother_till'])
		current = time.localtime(time.time()).tm_hour
		if till > since:
			return current not in range(since, till)
		else:
			return not (current in range(since, 25) or
						current in range(-1, till))

	def log(self, text):
		return 'Ear：' + text