#!/usr/bin/env python
# -*- coding: utf-8 -*-
from .models import *
import datetime
import sense_core as sd
from . import email_base, utils
from .share_interface import Share
from .check_db_exist import check_db_exist

sd.log_init_config(root_path=sd.config('log_path'))


class MonitEmialSender(object):
	
	def _send_err_email(self, module, title, subject = "网站日志监控", receiver_email=None):
		db = check_db_exist()
		module_config = {}
		email_list = []
		if receiver_email:
			if type(receiver_email) == list:
				email_list = receiver_email
			elif type(receiver_email) == str:
				email_list = [receiver_email]
		else:
			if not db:
				return None
			else:
				module_config = Share.get_module_config(module)
				email_list = Share.get_contact_list(module_config['user'], 'email')
		send_res = self._send_email(module, title, subject, email_list)
		suc_email = []
		fail_email = []
		if not send_res or send_res == '':
			sd.log_info('[*] Module ' + module + ' errors email has send failed.')
		else:
			suc_email, fail_email = self._check_send_result(send_res)
			if fail_email and len(fail_email) != 0:
				suc_list, fail_list = self._resend_email(module, fail_email, subject, title)
				suc_email.extend(suc_list)
				fail_email = fail_list
		if not db:
			sd.log_info('The success send email is:{}, the failed send email is:{}'.format(suc_email, suc_email))
		else:
			try:
				self._update_email_db(module, title, str(module_config['user']), suc_email, fail_email)
			except Exception as e:
				self._update_email_db(module, title, str([]), suc_email, fail_email)

	
	def _send_email(self, module, title, subject, email_list=None):
		_now = datetime.datetime.now()
		msg_res = self._send_email_detail(module, email_list, subject, title)
		return msg_res
	
	def _get_last_send_time(self, module_name):
		email_send_log = EmailSendLog()
		session = email_send_log.get_session()
		email_send = session.query(EmailSendLog).filter(EmailSendLog.module == module_name).order_by("time").all()
		if email_send:
			last_time = email_send[-1].time
		else:
			last_time = datetime.datetime.strptime("2019-01-01 00:00:00", "%Y-%m-%d %H:%M:%S")
		email_send_log.close_session(session)
		return last_time
	
	def _check_send_result(self, send_res):
		suc_email, fail_email = [], []
		if send_res['code'] == 'OK':
			suc_email = send_res['addr']
		elif send_res['code'] == 'Failed':
			suc_email = send_res['suc_list']
			fail_email = send_res['failed_list']
		return suc_email, fail_email
	
	def _update_email_db(self, module_name, content, uid, success_email, fail_email):
		email_send_log = EmailSendLog()
		session = email_send_log.get_session()
		_now = datetime.datetime.now()
		if success_email and len(success_email) != 0:
			for item in success_email:
				bulk_object = EmailSendLog(module=module_name, content=content, uids=uid, email=item,
										   status='success', time=_now)
				session.add(bulk_object)
		if fail_email and len(fail_email) != 0:
			for item in fail_email:
				bulk_object = EmailSendLog(module=module_name, content=content, uids=uid, email=item,
										   status='failed', time=_now)
				session.add(bulk_object)
		try:
			session.commit()
		except Exception as e:
			sd.log_warn('update err email db occur error:{0}'.format(e))
		finally:
			email_send_log.close_session(session)
	
	def _send_email_detail(self, module, email_list, subject, title):
		if not email_list or len(email_list) == 0:
			sd.log_info('The receiver email is empty')
			return {}
		_res = email_base.send_email(module, email_list, subject, title)
		res = self._is_mail_failed(_res)
		if res:
			_res = utils.build_dic(code='Failed', flag='email', failed_list=res)
		else:
			_res = utils.build_dic(code='OK', flag='email', addr=email_list)
			sd.log_info('email send successful!!!')
		return _res
	
	def _resend_email(self, module, fail_email, subject, title):
		success_list = []
		fail_list = fail_email
		if fail_email and len(fail_email) != 0:
			i = 1
			while i < 3:
				sd.log_info('email send fail, the failed email address is {}, now try {} resend'.format(fail_list, i))
				email_res = self._send_email_detail(module, fail_email, subject, title)
				if email_res['code'] == 'OK':
					success_list.extend(fail_email)
					fail_list = []
					break
				elif email_res['code'] == 'Failed':
					fail_list = email_res['failed_list']
					success_list.extend(email_res['suc_list'])
				i += 1
		return success_list, fail_list
	
	def _is_mail_failed(self, res):
		if not isinstance(res, dict):
			return []
		if len(res) == 0:
			return False
		return list(res.keys())
