﻿  #!C:\Python\Python311\python.exe
# -*- coding: utf-8 -*-
# cl_man_req.py .  03-10-202318:11 
 
import sys
import re
import datetime
import time
import zoneinfo
from datetime import  timezone 

from collections import abc
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email import encoders
from email.header import Header
import json
import platform

if platform.system() == "Windows":
    # print("Windows WindowsWindows Windows Windows ")
    s = "H:\\colect\\biblioteka\\programs\\LiClipse 10.0.0\\LiClipse Workspace\\Telegram_ESP32WebApp\\"
    # s2 = "H:\\colect\\biblioteka\\programs\\LiClipse 10.0.0\\LiClipse Workspace\\Telegram_ESP32WebApp\\man_db\\"
    pass
else:
    # print("Linux  Linux Linux Linux Linux Linux  ") 
    # sys.path.insert(0, '/opt/Telegram_ESP32/')  # todo
    s = '/opt/Telegram_ESP32/'
    pass           

sys.path.insert(0, s)
# sys.path.insert(0, s2)
sys.path.insert(0, '../..')
sys.path.insert(0, '..')
sys.path.insert(0, '*')

from utils.consts import clC

from man_db.clManTEMP_DB import  clManTEMP_DB
from man_db.clManTZone_DB import  clManTZone_DB
from man_db.clManEmail_DB import  clManEmail_DB

from man_db.MDB import   clMLog
from man_db.MDB import clMDB  

from man_db.MDB import   clMLogRequest
v_clManTEMP_DB = clManTEMP_DB()
v_clManTZone_DB = clManTZone_DB()
v_clManEmail_DB = clManEmail_DB()

v_clMDB = clMDB()
v_clMLog = clMLog()
v_clMLogRequest = clMLogRequest()
   
CONN_SECURITY_SSL = "SSL/TLS"


class cl_man_req(object):
    '''    
 
    '''
 
    dict_v = {}

    def __init__(self):
        pass

    @staticmethod
    def Convert_to_date(dictRes, app):  #  # 28-10-20236:51 
        Name_o_key = "DT"
        dict_keys = dictRes.keys()
        for key in dict_keys:
            if isinstance(dictRes[key], abc.Mapping):
                app.logger.warning("cl_man_req Convert_to_date dict >>> %s", dictRes[key])
                o_dict_keys = dictRes[key].keys()
                if "TIME" in o_dict_keys:
                    Name_o_key = "TIME"
    
                app.logger.warning("cl_man_req Convert_to_date o_dict_keys >>> %s", o_dict_keys)
                app.logger.warning("cl_man_req Convert_to_date Name_o_key >>> %s", Name_o_key)
                
                dictRes[key][Name_o_key] = datetime.datetime.fromtimestamp(dictRes[key][Name_o_key]).isoformat()
                # return [dict_or_list]
            else:
                app.logger.warning("cl_man_req Convert_to_date list >>> %s", dictRes[key][0])
                for i in range(len(dictRes[key])): 
                    dictRes[key][i][Name_o_key] = datetime.datetime.fromtimestamp(dictRes[key][i][Name_o_key]).isoformat()
                    print(dictRes[key][i][Name_o_key])
            #
        return dictRes

    @staticmethod
    def Ch_lang(id_telegram, lang_new, app):  #  
        ans = v_clMDB.Ch_lang(id_telegram, lang_new)
        app.logger.warning("cl_man_req Ch_lang ans >>> %s", ans)
        return ans

    @staticmethod
    def ChTZone(mac, tzone, app):  #  #28-10-20236:51
        ans = v_clManTZone_DB.ChTZone_BYmac(mac, tzone)
        app.logger.warning("cl_man_req ChTZone ans >>> %s", ans)
        return ans

    @staticmethod
    def is_win(): 
        if platform.system() == "Windows":
            is_win = 1
        else:
            is_win = 0
        return is_win

    @staticmethod
    def get_lang(id_telegram, language_code, app):  # id_telegram
        app.logger.warning("cl_man_req get_lang id_telegram >>> %s", id_telegram)
        clC.ID_lang = v_clMDB.get_id_lang(id_telegram, language_code)
        
        return clC.ID_lang

    @staticmethod
    def get_TZONE_BYmac(mac, app):  #  #28-10-20236:51
        app.logger.warning("cl_man_req get_TZONE_BYmac mac >>> %s", mac)
        tzone = v_clManTZone_DB.get_TZONE_BYmac(mac)
        return tzone

    @staticmethod
    def get_macByAPI_KEY(API_KEY, app):  # 26-10-202318:26
        # v_clMLog.INSERTrow(666666666, 23, 2134)
        mac = v_clManTEMP_DB.get_macByAPI_KEY(API_KEY)
        app.logger.warning("cl_man_req get_macByAPI_KEY API_KEY >>> %s", API_KEY)
        app.logger.warning("cl_man_req get_macByAPI_KEY mac >>> %s", mac)
        return mac
    
    @staticmethod
    def get_macByAPI_KEY2(API_KEY, app):  # 26-10-202318:26
        # v_clMLog.INSERTrow(666666666, 23, 2134)
        mac = v_clManTEMP_DB.get_macByAPI_KEY2(API_KEY)
        app.logger.warning("cl_man_req get_macByAPI_KEY2 API_KEY >>> %s", API_KEY)
        app.logger.warning("cl_man_req get_macByAPI_KEY2 mac >>> %s", mac)
        return mac
    
    @staticmethod
    def get_macBy_name_deviceAndIdUserGrafana(name_device, id_user_grafana, login_user_grafana, app):  # 06-11-202319:04
        id_telegram = v_clManTEMP_DB.get_id_telegramByIdUserGrafana(id_user_grafana)
        mac = v_clManTEMP_DB.get_macBy_id_telegramAnd_name_device(name_device, id_telegram, id_user_grafana, login_user_grafana)
        app.logger.warning("cl_man_req get_macBy_name_deviceAndIdUserGrafana mac >>> %s", mac)
        return mac
    
    @staticmethod
    def get_emails(emails):  # 01-11-202318:59 
        emails = emails.replace("  ", " ")
        emails = emails.strip()
        ar_emails = emails.split(clC.StrSpliterB)
        print(" get_emails")
        print(ar_emails)
        if len(ar_emails) == 0:
            return  False
            
        for email in ar_emails:
            # email='foo@examplecom'
            if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
                print(" not email ")
                return  False
            # else:
            #     print(" +++++++++email " )
        if len(ar_emails) > clC.MaxNumEmailRecipients:
            return  False
        
        return ar_emails

    @staticmethod
    def request_recipient(API_KEY, request_data, app):  # 01-11-202318:59 
        ans_emails = cl_man_req.get_emails(request_data["EMAIL"])
        # print(" ans_emails")
        # print(str(type(ans_emails)))
        # print(ans_emails)
        
        # if ans_emails != True:
        #     return 0
        if str(type(ans_emails)) != "<class 'list'>":
            return 0
       
        mac = cl_man_req.get_macByAPI_KEY2(API_KEY, app)
        if mac == 0:
            return 0
        ans = 0
        try:
            ans = v_clManEmail_DB.request_recipient(request_data, mac) 
            print("request_recipient       ans")
            print(ans)  # the exception type
                      
        except Exception as inst:
            print("request_recipient       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req request_recipient ans >>> %s", ans)
        return ans

    @staticmethod
    def send_email(SMTP_server_name, PORT, USER, PWD, CONN_SECURITY,
                    recipient, subject, body):  # 02-11-202310:00
        ans = 0
        FROM = USER
        TO = recipient if isinstance(recipient, list) else [recipient]
        TO = ', '.join(recipient)
        SUBJECT = subject
        # TEXT = body.decode('UTF-8')
        # body = body.decode('utf-8', 'ignore')
        # body="Попытка"
        # new_json={"kkk":body}
        # body=json.dumps(new_json)
        msg = MIMEMultipart()
        msg['From'] = FROM
        msg['To'] = TO
        msg['Subject'] = Header(SUBJECT, 'utf-8')        
        msgT = f"Subject:{subject}\n\n{body}".encode('utf-8')
        
        try:
            # body = 'This is the body of the email'
            # msg.attach(MIMEText(body.encode('utf-8'), 'plain', 'utf-8'))
            msg.attach(MIMEText(body, 'plain', 'utf-8'))
            # msg.attach(MIMEText(msgT, 'plain', 'utf-8'))
            # message = """From: %s\nTo: %s\nSubject: %s\n\n%s
            # """ % (FROM, ", ".join(TO), SUBJECT, TEXT)
            # server = smtplib.SMTP('smtp.gmail.com', 587)
            # server.starttls()
            # server.login('sender@example.com', 'password')
            # text = msg.as_string()
            # server.sendmail('sender@example.com', 'recipient@example.com', text)
            # server.quit()
           
            server_ssl = smtplib.SMTP_SSL(SMTP_server_name, PORT)
            # server_ssl =""
            # Prepare actual message
            try:
                # SMTP_SSL Example
                server_ssl.ehlo()  # optional, called by login()
                server_ssl.login(USER, PWD)  
                # ssl server doesn't support or need tls,
                # so don't call server_ssl.starttls() 
    # starttls() is a way to take an existing insecure connection
    # and upgrade it to a secure connection using SSL/TLS.
    # server.starttls()
                
                # if CONN_SECURITY == CONN_SECURITY_SSL:
                #   server_ssl.starttls()

# https://stackoverflow.com/questions/19390267/python-3-smtplib-exception-ssl-wrong-version-number-logging-in-to-outlook
# import ssl
# context = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
# connection = smtplib.SMTP('smtp-mail.outlook.com', 587)
# connection.ehlo()
# connection.starttls(context=context)
# connection.ehlo()
# connection.login('now_your_real_login_data@outlook.com', 'otherwise_SMTPServerDisconnect')
   
                # `AUTH_METHOD` varchar(125) NOT NULL, todo
                text = msg.as_string()    
                server_ssl.sendmail(FROM, TO, text)  # d--
                # server_ssl.sendmail(FROM, TO, message)  # d--
                # server_ssl.quit()
                # server_ssl.close()
                print ('successfully sent the mail')
                ans = clC.resultOK
            except Exception as err:
                saved_args = locals()
                print("saved_args is", saved_args)
                print ('Error sending email: ', err)
                ans = str(err)
            finally:
                server_ssl.close()    
        except Exception as err:
            saved_args = locals()
            print("saved_args is", saved_args)
            print ('Error sending email0: ', err)
            ans = str(err)
        return  ans   
            
    @staticmethod
    def request_email(API_KEY, request_data, app):  # 02-11-202310:00
        
        mac = cl_man_req.get_macByAPI_KEY2(API_KEY, app)
        if mac == 0:
            return clC.resultEmailNotValid
        
        EMAIL = v_clManEmail_DB.get_emailsDB(mac)
        if EMAIL == 0:
            return clC.resultEmailNotValid
        ans_emails = cl_man_req.get_emails(EMAIL)
        # print(" ans_emails")
        # print(str(type(ans_emails)))
        # print(ans_emails)

        one = v_clManEmail_DB.get_smtp(mac) 
        if one == 0:
            return clC.resultEmailNotValid
        
        ans = cl_man_req.send_email(
            one["SMTP_server_name"],
            one["PORT"],
            one["USER"],
            one["PWD"],
            one["CONN_SECURITY"],
                    ans_emails,
            request_data["SUBJ"],
            request_data["BODY"]
                )
        # if ans == 0:
        #     return clC.resultEmailNotValid
        
        app.logger.warning("cl_man_req request_email ans >>> %s", ans)
        return ans

    @staticmethod
    def request_smtp(API_KEY, request_data, app):  # 01-11-202316:35
        mac = cl_man_req.get_macByAPI_KEY2(API_KEY, app)
        if mac == 0:
            return 0
        ans = 0
        try:
            ans = v_clManEmail_DB.request_smtp(request_data, mac) 
            print("request_smtp       ans")
            print(ans)  # the exception type
                      
        except Exception as inst:
            print("request_smtp       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req request_smtp ans >>> %s", ans)
        return ans

    @staticmethod
    def get_list_name_device_ByIdUserGrafana(request_data, app):  # 06-11-202313:03
        
        dictRes = {}
        try:
            dictRes = v_clManTEMP_DB.get_list_name_device_ByIdUserGrafana(request_data)
            print("get_list_name_device_ByIdUserGrafana  dictRes")
            print(dictRes)  # the exception type
                      
        except Exception as inst:
            print("get_list_name_device_ByIdUserGrafana       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req get_list_name_device_ByIdUserGrafana dictRes >>> %s", dictRes)
        return dictRes

    @staticmethod
    def get_records_t(API_KEY, request_data, app):  # 27-10-202314:39
        mac = cl_man_req.get_macByAPI_KEY(API_KEY, app)
        if mac == 0:
            return 0
        
        dictRes = {}
        try:
            tzone = cl_man_req.get_TZONE_BYmac(mac, app)
            dictRes[mac] = v_clManTEMP_DB.get_records_t(request_data, mac, tzone) 
            try:
                # DateF=request_data["d"]
                if request_data["d"]:
                    dictRes = cl_man_req.Convert_to_date(dictRes, app)
                
                # dictRes =cl_man_req.Convert_to_date(dictRes, app)
            except Exception as inst:
                pass
            # x = DateF if True else dictRes
            print("get_records_t       dictRes")
            print(dictRes)  # the exception type
                      
        except Exception as inst:
            print("get_records_t       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req get_records_t mac >>> %s", mac)
        return dictRes

    @staticmethod
    def get_logs_name_device(request_data, app):  # 11-11-202310:46  
        mac = cl_man_req.get_macBy_name_deviceAndIdUserGrafana(request_data["name_device"], request_data["id_user"], request_data["login_user_grafana"], app)
        if mac == 0:
            return 0
        
        dictRes = {}
        try:
            # tzone =0
            print(sys.version)
            request_data["DTS"] = request_data["DTS"].replace("Z", "+00:00")
            print (str(request_data["DTS"]))            
            request_data["DTF"] = request_data["DTF"].replace("Z", "+00:00")
            print (str(request_data["DTF"]))            
                
            curr_dt = datetime.datetime.fromisoformat(request_data["DTS"])
            request_data["DTS"] = int(time.mktime(curr_dt.timetuple()))
            curr_dt = datetime.datetime.fromisoformat(request_data["DTF"])
            request_data["DTF"] = int(time.mktime(curr_dt.timetuple()))
 
            print (str(request_data["DTS"]))            
            print (str(request_data["DTF"]))    
                     
            print("get_logs_name_device  request_data timezone ")
            print(request_data["timezone"])  
            tzone = 0
            # [mac]
            dictRes[mac] = v_clManTEMP_DB.get_logs_name_device(request_data, mac, tzone, tzone) 
            try:
                # DateF=request_data["d"]
                if request_data["d"]:
                    print("get_logs_name_device   request_data d ")
                    print(request_data["d"])  
                    dictRes = cl_man_req.Convert_to_date(dictRes, app)
                
                # dictRes =cl_man_req.Convert_to_date(dictRes, app)
                dictRes = dictRes[mac]
            except Exception as inst:
                pass
            # x = DateF if True else dictRes
            print("get_logs_name_device       dictRes")
            print(dictRes)  # the exception type
                      
        except Exception as inst:
            print("get_logs_name_device       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req get_logs_name_device mac >>> %s", mac)
        return dictRes

    @staticmethod
    def get_records_t_name_device(request_data, app):  # 06-11-202319:04
        mac = cl_man_req.get_macBy_name_deviceAndIdUserGrafana(request_data["name_device"], request_data["id_user"], request_data["login_user_grafana"], app)
        if mac == 0:
            return 0
        
        dictRes = {}
        try:
            # tzone =0
            request_data["DTS"] = request_data["DTS"].replace("Z", "+00:00")
            print (str(request_data["DTS"]))            
            request_data["DTF"] = request_data["DTF"].replace("Z", "+00:00")
            print (str(request_data["DTF"]))            
            curr_dt = datetime.datetime.fromisoformat(request_data["DTS"])
            request_data["DTS"] = int(time.mktime(curr_dt.timetuple()))
            curr_dt = datetime.datetime.fromisoformat(request_data["DTF"])
            request_data["DTF"] = int(time.mktime(curr_dt.timetuple()))
            # if platform.system() != "Windows":
            #     request_data["DTS"] =request_data["DTS"] -10800
            #     request_data["DTF"] =request_data["DTF"] -10800
            print (str(request_data["DTS"]))            
            print (str(request_data["DTF"]))    
                     
            print("get_records_t_name_device  request_data timezone ")
            print(request_data["timezone"])  
            # td = (datetime.datetime.now(zoneinfo.ZoneInfo(request_data["timezone"])).utcoffset())
            # td_int = int(td.total_seconds())
            # # tzone = cl_man_req.get_TZONE_BYmac(mac, app)
            # tzone = td_int / 3600 
            # print("get_records_t_name_device   timezone ")
            # print(tzone)  
            tzone = 0
            # [mac]
            dictRes[mac] = v_clManTEMP_DB.get_records_t(request_data, mac, tzone, tzone) 
            try:
                # DateF=request_data["d"]
                if request_data["d"]:
                    print("get_records_t_name_device   request_data d ")
                    print(request_data["d"])  
                    dictRes = cl_man_req.Convert_to_date(dictRes, app)
                
                # dictRes =cl_man_req.Convert_to_date(dictRes, app)
                dictRes = dictRes[mac]
            except Exception as inst:
                pass
            # x = DateF if True else dictRes
            print("get_records_t_name_device       dictRes")
            print(dictRes)  # the exception type
                      
        except Exception as inst:
            print("get_records_t_name_device       Exception")
            print(type(inst))  # the exception type
            print(inst.args)  # arguments stored in .args
            print(inst)  # __str__ allows args to be printed directly,
        
        app.logger.warning("cl_man_req get_records_t_name_device mac >>> %s", mac)
        return dictRes

    @staticmethod
    def get_last_t(API_KEY, request_data, app):  # 26-10-202318:26
        mac = cl_man_req.get_macByAPI_KEY(API_KEY, app)
        if mac == 0:
            return 0
        
        tzone = cl_man_req.get_TZONE_BYmac(mac, app)

        ans = v_clManTEMP_DB.get_last_t(mac, tzone)
        app.logger.warning("cl_man_req get_last_t ans >>> %s", ans)
        dictRes = {}
        dictRes["T"] = ans
        try:
            # DateF=request_data["d"]
            if request_data["d"]:
                dictRes = cl_man_req.Convert_to_date(dictRes, app)
        except Exception as inst:
            pass
        ans = dictRes["T"]
        app.logger.warning("cl_man_req get_last_t 2 ans >>> %s", ans)
        
        return ans

# 
    @staticmethod
    def reg_t_debug(t, mac, time, IP, app):  # 05-11-202318:48
        # logging.info('cl_man_req reg_t')
        ans = v_clManTEMP_DB.reg_t_debug(t, mac, time, IP)
        app.logger.warning("cl_man_req reg_t_debug ans >>> %s", ans)
        return ans

    @staticmethod
    def regRequest(request , mac , app, API_KEY="", forSalt2=False):  # 10-11-202314:01
        dict_action = {
            "reg_t":"reg_t",  #
            "get_last_t":"get_last_t",  #
            "get_records_t":"get_records_t",  #
            "smtp":"smtp",
            "recipient":"recipient",
            "email":"email" 
        }
        valueG = ""
        valueP = ""
        
        path = request.path
        
        # method = request.method
        if mac == "":
            if forSalt2 == False:
                mac = cl_man_req.get_macByAPI_KEY(API_KEY, app)
            else:
                mac = cl_man_req.get_macByAPI_KEY2(API_KEY, app)
            if mac == 0:
                return 0
        if 't' in request.args:
            action = dict_action["reg_t"]
            
        if mac != "" and API_KEY != "":
            action = dict_action["get_last_t"]
        # action=request.full_path
        try:
            valueP = request.get_json()
            ar_keys = valueP.keys()
            if mac != "" and  "DTS" in ar_keys:
                action = dict_action["get_records_t"]
                
            if path.find("smtp") != -1:
                action = dict_action["smtp"]
            if path.find("recipient") != -1:
                action = dict_action["recipient"]
            if path.find("email") != -1:
                action = dict_action["email"]
          
        except Exception:
            pass       

        valueG = request.args
        valueG = valueG.to_dict()
        if len(valueG.items()) == 0:
            valueG = ""
        else:
            valueG = str(valueG)
        valueP = str(valueP)
        value = valueG + valueP
       
        app.logger.warning("cl_man_req regRequest action value>>> %s %s" % (action, value))
        # app.logger.warning("cl_man_req regRequest value >>> %s", value)
        ans = v_clMLogRequest.regRequest(mac, request.remote_addr, path, action , value)
        app.logger.warning("cl_man_req regRequest ans >>> %s", ans)
        return ans

    @staticmethod
    def reg_t(t, mac, firmware_number, IP, app):  # 25-10-202321:36
        # logging.info('cl_man_req reg_t')
        ans = v_clManTEMP_DB.reg_t(t, mac, firmware_number, IP)
        app.logger.warning("cl_man_req reg_t ans >>> %s", ans)
        return ans

    def Set_init(self, dict_v):
        self.Real_parameter_size = 0
        self.dict_v = dict_v
        # self.dict_v = dict_v["mail_name"]
        # self.mail_name = dict_v["mail_name"]
        pass
