#-------------------------------------------------------------------------------
# Name:        Mail Manager
# Purpose:     Allows the notification per mail when the experimental campaign is stopped
#              
# Author:      Eric N
#
# Last Version:22.09.2022
# Copyright:   (c) Institute of technical biocatalysis TUHH
# Licence:     GNU GPL-v3
#-------------------------------------------------------------------------------
import smtplib
import email.utils
from email.mime.text import MIMEText
from getpass import getpass

import datetime
import pytz

maxAttempts = 5

class MailManager:

    def __init__(self,receiver_add) -> None:
        # setup
        self.sender_add = 'automatedExperiment@gmail.com'
        self.receiver_add = receiver_add
        self.loggedIn = False

        self.initialLogin()

    def initialLogin(self):
        self.connectToServer()
        self.getLoginData()
        self.disconnectFromServer()
    
    def connectAndSend(self):
        self.connectToServer()
        self.logIntoAccount()
        self.sendBaseMail()
        self.disconnectFromServer()

    def connectToServer(self):
        # currently only working for gmail
        # creating the SMTP server object by giving SMPT server address and port number
        self.smtp_server=smtplib.SMTP("smtp.gmail.com",587)
        self.smtp_server.ehlo() #setting the ESMTP protocol
        self.smtp_server.starttls() #setting up to TLS connection
        self.smtp_server.ehlo() #calling the ehlo() again as encryption happens on calling startttls()

    def getLoginData(self):
        n = 0
        while n < maxAttempts and not self.loggedIn:
            self.login_add = input('Login-Adress:\n')
            self.password = getpass()
            n += 1
            try:
                self.logIntoAccount()
                self.loggedIn = True
                print('Logged in successfully!\n')
            except:
                print('Please try again (%i/%i attempts)!'%(n,maxAttempts))
        if not self.loggedIn:
            print('Login failed. Continuing without email confirmation.\n')
        else:
            pass

    def logIntoAccount(self):
        self.smtp_server.login(self.login_add,self.password)

    def sendBaseMail(self):
        # Create the message
        current_time = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
        msg = MIMEText('Experiments stoped at %s.'%current_time)
        msg['Subject'] = 'Run Stopped'
        self.sendMail(msg)
        
    def sendFinishMail(self):
        # Create the message
        current_time = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
        msg = MIMEText('Experiments finished at %s.'%current_time)
        msg['Subject'] = 'Run Finished Successfully'
        self.sendMail(msg)

    def sendErrorMail(self):
        # Create the message
        current_time = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
        msg = MIMEText('Experiments stoped at %s.'%current_time)
        msg['Subject'] = 'Run Stopped Due To An Error'
        self.sendMail(msg)

    def sendMail(self,msg):
        msg['To'] = email.utils.formataddr(('Researcher', self.receiver_add))
        msg['From'] = email.utils.formataddr(('Automated Experiment Run', self.sender_add))
        if self.loggedIn:
            try:
                self.smtp_server.sendmail(self.sender_add, self.receiver_add, msg.as_string())
            except:
                print('Failed to send the following email (error): %s'%msg['Subject'])
        else:
            print('Failed to send the following email (not logged in): %s'%msg['Subject'])

    def disconnectFromServer(self):
        self.smtp_server.quit()


if __name__=='__main__':
    receiver_add = 'eric.nitschke@tuhh.de'
    manager = MailManager(receiver_add)
    manager.connectAndSend()