#!/usr/bin/python3

import json
import sqlite3
from db import *
from globalSettings import *
from global_func import *
import cgi
import cgitb
from clearTextPwd import *
cgitb.enable()


# email test
import socket
import smtplib
from email.mime.text import MIMEText

conn = sqlite3.connect(DBPath)
conn.text_factory = str
c = conn.cursor()

device = DeviceName


if (GUI == true):
    form = cgi.FieldStorage()
    request_Type = form.getvalue('requestType')

else:
    print("1.Create Email")
    print("2.Update Email")
    print("3.Delete Email")
    print("4.Read Email")
    choice = int(input("select cgi Function===>"))
    if choice == 1:
        request_Type = 'create_email'
    elif choice == 2:
        request_Type = 'update_email'
    elif choice == 3:
        request_Type = 'delete_email'
    elif choice == 4:
        request_Type = 'read_email'
    else:
        print("Enter Valid choice")
    print("Reques_Type="+str(request_Type))


def form_getvalue(val):
    if val == "name":
        name = str(input("Enter name of the email: "))
        return name
    if val == "state":
        state = str(input("Enter state of the email: "))
        return state
    if val == "level":
        level = str(input("Enter level of the email: "))
        return level
    if val == "user":
        user = str(input("Enter user of the email: "))
        return user
    if val == "pw":
        pw = str(input("Enter pw of the email: "))
        return pw
    if val == "out_server":
        out_server = str(input("Enter out_server of the email: "))
        return out_server
    if val == "in_server":
        in_server = str(input("Enter in_server of the email: "))
        return in_server
    if val == "authentication":
        authentication = str(input("Enter authentication of the email: "))
        return authentication
    if val == "smtp_server":
        smtp_server = str(input("Enter smtp_server of the email: "))
        return smtp_server
    if val == "port_number":
        port_number = str(input("Enter port_number of the email: "))
        return port_number
    if val == "alert_msg":
        alert_msg = str(input("Enter alert_msg of the email: "))
        return alert_msg
    if val == "id":
        id = str(input("Enter id of the email: "))
        return id

def is_valid_port(smtp_server,port):
    try:
        # Create a socket object
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Set a timeout to avoid waiting indefinitely
        sock.settimeout(1)

        # Try connecting to the server on the given port
        result = sock.connect_ex((smtp_server, int(port)))

        # Close the socket
        sock.close()

        # If the result is 0, the port is open and valid
        return result == 0
    except Exception as e:
        # An error occurred (invalid port or server not reachable)
        return False

def is_valid_smtp_server(smtp_server):
    try:
        # Get the IP address of the SMTP server
        ip_address = socket.gethostbyname(str(smtp_server))

        # Create a socket object
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Set a timeout to avoid waiting indefinitely
        sock.settimeout(1)

        # Try connecting to the SMTP server on port 25 (standard SMTP port)
        result = sock.connect_ex((ip_address, 25))

        # Close the socket
        sock.close()

        # If the result is 0, the server is reachable and valid
        return result == 0
    except Exception as e:
        # An error occurred (invalid server or server not reachable)
        return False

def create_email():
    cmd = "create"
    cmd_id = get_ccm_command_id()
    if(GUI == true):
        name = form.getvalue("name")
        state = 1  # form.getvalue("state")
        level = form.getvalue("level")
        user = form.getvalue("user")
        pw = (form.getvalue("pw"))
        out_server = form.getvalue("out_server")
        in_server = form.getvalue("in_server")
        authentication = form.getvalue("authentication")
        smtp_server = form.getvalue("smtp_server")
        port_number = form.getvalue("port_number")
        alert_msg = form.getvalue("alert_msg")
    else:
        name = form_getvalue("name")
        state = form_getvalue("state")
        level = form_getvalue("level")
        user = form_getvalue("user")
        pw = (form_getvalue("pw"))
        out_server = form_getvalue("out_server")
        in_server = form_getvalue("in_server")
        authentication = form_getvalue("authentication")
        smtp_server = form_getvalue("smtp_server")
        port_number = form_getvalue("port_number")
        alert_msg = form_getvalue("alert_msg")
    query = c.execute("select count(*) from email")
    nameCount = c.fetchone()[0]

    try:
        # if not is_valid_smtp_server(smtp_server):
        #     print((json.JSONEncoder().encode(
        #         {"status": "fail", "description": "Invalid Smtp Server!"})))
        #     return False
        if authentication == 'true':
            if not is_valid_port(smtp_server,port_number):
                print((json.JSONEncoder().encode(
                    {"status": "fail", "description": "Invalid Port Number!"})))
                return False
            mailserver = smtplib.SMTP(smtp_server, port_number)
            mailserver.starttls()
            mailserver.login(in_server,pw)
            mailserver.quit()
    except Exception as e:
        # print(e)
        print((json.JSONEncoder().encode(
                {"status": "fail", "description": "Invalid Sender Email and Password!","type" : "invalid"})))
        return False
    pw = (pw)
    if (CCM == true):
        if nameCount == 0:
            out_server = out_server.replace(",", ";")
            if level:
                level = level.strip(",").replace(",", ";")
            message = "set,element=email,args=14,uuid={0},action={1},state={2},level={3},pw={4},out_server={5},in_server={6},authentication={7},smtp_server={8},port_number={9},alert_msg={10},device={11}"\
                .format(cmd_id, cmd, state, level, pw, out_server, in_server, authentication, smtp_server, port_number, alert_msg, device)
            send_ccm_msg(message)
            response = get_ccm_response(cmd_id)
            print(response)
            delete_ccm_response(cmd_id)
        else:
            update_email()

    else:
        if (nameCount == 0):
            query = c.execute("insert into email(name,state,level,user,pw,out_server,in_server,authentication,smtp_server,port_number,alert_msg,cr_date ) values(?,?,?,?,?,?,?,?,?,?,?,datetime())", [
                              name, state, level, user, pw, out_server, in_server, authentication, smtp_server, port_number, alert_msg])
            conn.commit()
            print((json.JSONEncoder().encode(
                {"status": "success", "description": "Successfully Created"})))
        else:
            update_email()

    # c.close()
    # conn.close()


def update_email():
    cmd = "update"
    cmd_id = get_ccm_command_id()
    if(GUI == true):
        name = form.getvalue("name")
        state = 1  # form.getvalue("state")
        level = form.getvalue("level")
        user = "-"  # form.getvalue("user")
        pw = form.getvalue("pw")
        out_server = form.getvalue("out_server")
        in_server = form.getvalue("in_server")
        authentication = form.getvalue("authentication")
        smtp_server = form.getvalue("smtp_server")
        port_number = form.getvalue("port_number")
        alert_msg = form.getvalue("alert_msg")
        id = form.getvalue("id")
    else:
        name = form_getvalue("name")
        state = form_getvalue("state")
        level = form_getvalue("level")
        user = form_getvalue("user")
        pw = form_getvalue("pw")
        out_server = form_getvalue("out_server")
        in_server = form_getvalue("in_server")
        authentication = form_getvalue("authentication")
        smtp_server = form_getvalue("smtp_server")
        port_number = form_getvalue("port_number")
        alert_msg = form_getvalue("alert_msg")
        id = form_getvalue("id")
    query = c.execute(
        "select count(*) from email where name=? and id not like ?", [name, id])
    nameCount = c.fetchone()[0]
    if authentication == 'true':
        pw = (pw)

    if (CCM == true):
        if nameCount == 0:
            out_server = out_server.replace(",", ";")
            level = level.strip(",").replace(",", ";")
            message = "set,element=email,args=14,uuid={0},action={1},state={2},level={3},pw={4},out_server={5},in_server={6},authentication={7},smtp_server={8},port_number={9},alert_msg={10},id={11},device={12}"\
                .format(cmd_id, cmd, state, level, pw, out_server, in_server, authentication, smtp_server, port_number, alert_msg, id, device)
            send_ccm_msg(message)
            response = get_ccm_response(cmd_id)
            print(response)
            delete_ccm_response(cmd_id)
        else:
            print((json.JSONEncoder().encode(
                {"status": "fail", "description": "Name Already exists"})))

    else:

        if (nameCount == 0):
            query = c.execute("update email set name=?,state=?,level=?,user=?,pw=?,out_server=?,in_server=?,authentication=?,smtp_server=?,port_number=?,alert_msg=?,edit_date=datetime() where id=?", [
                              name, state, level, user, pw, out_server, in_server, authentication, smtp_server, port_number, alert_msg, id])
            conn.commit()
            print((json.JSONEncoder().encode(
                {"status": "success", "description": "Successfully Updated"})))
        else:
            print((json.JSONEncoder().encode(
                {"status": "fail", "description": "Name Already exists"})))

    # c.close()
    # conn.close()


def delete_email():
    cmd = "delete"
    cmd_id = get_ccm_command_id()
    print("delete")
    if(GUI == true):
        id = form.getvalue("id")
        name = form.getvalue("name")
    else:
        id = form_getvalue("id")
        name = form_getvalue("name")
    if (CCM == true):
        message = "set,element=email,args=4,uuid={0},action={1},id={2},name={3},device={4}".format(
            cmd_id, cmd, id, name, device)
        send_ccm_msg(message)
        response = get_ccm_response(cmd_id)
        print(response)
        delete_ccm_response(cmd_id)
    else:
        try:
            query = c.execute("delete from email where  id="+str(id))
            conn.commit()
            print((json.JSONEncoder().encode(
                {"status": "success", "description": "Successfully Deleted"})))
        except Exception as err:
            print((json.JSONEncoder().encode(
                {"status": "fail", "description": "Failed to Delete "})))

    c.close()
    conn.close()


def read_email():
    cmd = "read"
    cmd_id = get_ccm_command_id()
    if(GUI == true):
        id = form.getvalue("id")
    else:
        id = form_getvalue("id")
    query = c.execute(
        "select name,state,level,user,pw,out_server,in_server,authentication,smtp_server,port_number,alert_msg,id from email")
    dbData = []
    for col in c:
        jsonSchema = {"name": col[0], "state": col[1], "level": col[2], "user": col[3], "pw": (col[4]), "out_server": col[5],
                      "in_server": col[6], "authentication": col[7], "smtp_server": col[8], "port_number": col[9], "alert_msg": col[10], "id": col[11]}
        dbData.append(jsonSchema)
    print(json.JSONEncoder().encode(dbData))


print("Content-type:text/html\r\n\r\n")

if(request_Type == 'create_email'):
    create_email()
elif(request_Type == 'update_email'):
    update_email()
elif(request_Type == 'delete_email'):
    delete_email()
else:
    read_email()
