#!/usr/bin/python3

import sqlite3
from global_func import *
import cgi
import cgitb
from clientConfiguration import *
import json
import uuid
import os
from db import *
from clearTextPwd import *
import base64

device = DeviceName


# to get the server port from the req
# server_port = os.environ["SERVER_PORT"]
# to connect to db according to server port
# conn = connect_to_db(server_port)
# c = conn.cursor()


cgitb.enable()
form = cgi.FieldStorage()
request_Type = form.getvalue('requestType')


def ValidateUser():
    userName = form.getvalue('userName')
    password = form.getvalue('password')
    if userName==None or password==None:
        print(json.JSONEncoder().encode({"status":"fail","description":"Empty UserName/Password"}))
        return
    decoded_username = (base64.b64decode(userName)).decode("utf-8")
    userName = decoded_username 
    decoded_password = (base64.b64decode(password)).decode("utf-8")
    password = decoded_password
    try:
        # print uuid.uuid4()
        query_lan = c.execute(
            "Select count(*) from person where userName=? or contactEmail=?", [str(userName), str(userName)])
        isUserExist = c.fetchone()[0]
        conn.commit()

        if isUserExist==0:
            print(json.JSONEncoder().encode({"status":"fail","description":"User Name does not exists"}))
            return
        #print (isUserExist)
        query_pwd = c.execute("select password from person where userName='"+str(userName+"'"))
        db_Pwd = c.fetchone()[0]
        conn.commit()

        isEnPwd = is_EncodedString_base64(db_Pwd)
        if db_Pwd == DEFAULT_PASSWORD:
            password = password
        
        elif not isEnPwd :
            EncPwd = pwd_encoding(password)
            updatePwd = c.execute("update person set password = '"+EncPwd+"' ")
            conn.commit()
            password = EncPwd
        
        else:
            #password = db_Pwd
            EncryptGUIpwd = pwd_encoding(password)
            password = EncryptGUIpwd

        query = "SELECT id,userName,FirstName,LastName,contactEmail from person where (userName='"+str(
            userName) + "' or contactEmail='"+str(userName) + "') and password='" + str(password) + "'"
        # print query
        query_lan = c.execute(query)
        isValidCredentials = c.fetchall()
        conn.commit()

        if isUserExist > 0:
            if isValidCredentials:
                default_password = False
                if password == DEFAULT_PASSWORD:
                    default_password = True
                attemptResult = ValidateAttempts(True)
                if attemptResult == False:
                    return

                query = "update person set login_time= datetime(),num_attempt=0 where userName='" + \
                    str(userName)+"' or contactEmail='"+str(userName)+"'"
                query_exec = c.execute(query)
                conn.commit()

                query = c.execute("SELECT id,userName,FirstName,LastName,contactEmail from person where (userName='"+str(
                    userName) + "' or contactEmail='"+str(userName) + "') and password='"+str(password)+"'")
                jsonUser = {}
                conn.commit()
                for col in c:
                    jsonUser = {"status": "success", "id": col[0], "userName": col[1], "FirstName": col[2], "LastName": col[3],
                                "contactEmail": col[4], "client": ClientName, "clientConfiguration": GetClientConfig(),"default_password": default_password}

                print(json.JSONEncoder().encode(jsonUser))
            else:
                ValidateAttempts(False)
                print(json.JSONEncoder().encode(
                    {"status": "fail", "description": "Invalid Credentials"}))
        else:
            print(json.JSONEncoder().encode(
                {"status": "fail", "description": "User Name does not exists"}))

        conn.close()
    except sqlite3.OperationalError as e:
        print(json.JSONEncoder().encode({"status": "fail", "description": "Login Credentials not found, Please check DB !!"}))
    except Exception as e:
        print(e)
        print(json.JSONEncoder().encode(
            {"status":"fail","description" :"Invalid Credentials"}
        ))


def ValidateAttempts(isValidUser):
    userName = form.getvalue('userName')
    userName = (base64.b64decode(userName)).decode("utf-8")
    FailedAttemptsCount = 0
    TimeLeftInSeconds = 0
    query = "select num_attempt, (CAST(strftime('%s', CURRENT_TIMESTAMP) as integer) - CAST(strftime('%s', login_time) as integer)) duration from person where userName='" + \
        str(userName)+"' or contactEmail='"+str(userName)+"'"
    query_exec = c.execute(query)
    conn.commit()
    for col in c:
        FailedAttemptsCount = col[0] if col[0] != None else 0
        TimeLeftInSeconds = col[1] if col[1] != None else 0

    if isValidUser == True:
        if (FailedAttemptsCount == 1 and TimeLeftInSeconds < 10):
            print(json.JSONEncoder().encode({"status": "fail", "description": "Please try after "+str(
                10 - TimeLeftInSeconds)+" seconds", "isUserBlocked": True, "timeLeft": 10 - TimeLeftInSeconds}))
            return False
        elif (FailedAttemptsCount == 2 and TimeLeftInSeconds < 20):
            print(json.JSONEncoder().encode({"status": "fail", "description": "Please try after "+str(
                20 - TimeLeftInSeconds)+" seconds", "isUserBlocked": True, "timeLeft": 20 - TimeLeftInSeconds}))
            return False
        elif (FailedAttemptsCount >= 3 and TimeLeftInSeconds < 60):
            print(json.JSONEncoder().encode({"status": "fail", "description": "Please try after "+str(
                60 - TimeLeftInSeconds)+" seconds", "isUserBlocked": True, "timeLeft": 60 - TimeLeftInSeconds}))
            return False

    elif isValidUser == False:
        query = "update person set login_time= datetime(),num_attempt=num_attempt+1 where userName='" + \
            str(userName)+"' or contactEmail='"+str(userName)+"'"
        query_exec = c.execute(query)
        conn.commit()

def ChangePassword():
    try:
        userName = form.getvalue('userName')
        password = form.getvalue('password')
        old_password = form.getvalue('old_password')
        old_password = (base64.b64decode(old_password)).decode("utf-8")
        password = (base64.b64decode(password)).decode("utf-8")
        userName = (base64.b64decode(userName)).decode("utf-8")
        

        
        query_lan=c.execute("Select count(*) from person where userName=? or contactEmail=?",[str(userName),str(userName)])
        isUserExist =c.fetchone()[0]
        conn.commit()
        #print (isUserExist)
        query = "SELECT id,userName,FirstName,LastName,contactEmail from person where (userName='"+str(userName) +"' or contactEmail='"+str(userName) +"') and password='"+ str((old_password)) + "'"
        #print query
        query_lan=c.execute(query)
        isValidCredentials =c.fetchall()
        conn.commit()

        if isUserExist > 0:
            if isValidCredentials:
                default_password = False
                if password == DEFAULT_PASSWORD:
                    default_password = True

                attemptResult = ValidateAttempts(True)
                if attemptResult == False:
                    return
                
                
                query = "update person set password='"+str(password)+"' where userName='"+str(userName)+"' or contactEmail='"+str(userName)+"'"
                query_exec=c.execute(query)
                conn.commit()

                query = "update person set login_time= datetime(),num_attempt=0 where userName='"+str(userName)+"' or contactEmail='"+str(userName)+"'"
                query_exec=c.execute(query)
                conn.commit()
                
                query = c.execute("SELECT id,userName,FirstName,LastName,contactEmail from person where (userName='"+str(userName) +"' or contactEmail='"+str(userName) +"') and password='"+str(password)+"'")
                jsonUser ={}
                conn.commit()
                for col in c:
                    jsonUser = {"status": "success", "id": col[0], "userName": col[1], "FirstName": col[2], "LastName": col[3],
                                "contactEmail": col[4], "client": ClientName, "clientConfiguration": GetClientConfig(),"default_password": default_password}

                
                print (json.JSONEncoder().encode(jsonUser))
                
            else:
                ValidateAttempts(False)
                print (json.JSONEncoder().encode({"status":"fail","description":"Invalid Credentials1"}))
        else:
            print (json.JSONEncoder().encode({"status":"fail","description":"User Name does not exists"}))
        c.close()
        conn.close()
    except Exception as e:
        c.close()
        conn.close()

def validatePassword():
    password = form.getvalue('password')
    password = (base64.b64decode(password)).decode("utf-8")
    query = c.execute(
        "Select count(*) from person where password=?", [str(password)])
    isvalidPassword = c.fetchone()[0]
    conn.commit()
    conn.close()
    print(json.JSONEncoder().encode({"isvalidPassword": isvalidPassword}))


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

if(request_Type == "validate_password"):
    validatePassword()
elif(request_Type == "ChangePassword"):
    ChangePassword()
else:
    ValidateUser()
