#!/usr/bin/python3

# -------------------------------------------------------------------------------------------
#   "CP Admin" website User Log In process, Incorporates HTML form 'cpadmin_login.html'
#   Verifies that the provided email and password match those in the Users table,
#   and that the User ID is marked is_active = 1

# print("Content-Type: text/plain\n")
# print("Script reached start")

import os
import sys
sys.stdout.reconfigure(encoding='utf-8')
import http.cookies
import json
import uuid
from dash_utils import get_connection, get_parameters
from password_utils import verify_password

# -------------------------------------------------------------------------------------------
from jinja2 import Environment, FileSystemLoader, Template
env = Environment(loader=FileSystemLoader('templates'), trim_blocks=True)

# -------------------------------------------------------------------------------------------
# functions
# -------------------------------------------------------------------------------------------

# -------------------------------------------------------------------------------------------
def render_form(tmpdict, cookie=None):
    template = env.get_template('./cpadmin_login.html')
    output = template.render(tmpdict)
    # Always emit headers
    print("Content-Type: text/html; charset=utf-8")
    if cookie:
        for morsel in cookie.values():
            print(morsel.OutputString())  # prints "Set-Cookie: ..."
    print()  # blank line after headers
    # Then emit HTML
    print(output)

# -------------------------------------------------------------------------------------------

import cgitb
cgitb.enable(display=1)

def main():

    method = os.environ.get("REQUEST_METHOD", "GET")
    if method == "POST":
        # Form submission

        # extract form values
        args_dict = get_parameters()
        email = args_dict.get('email', '').strip()
        password = args_dict.get('password', '')

        if not email or not password:
            args_dict['message'] = "All fields are required"
            args_dict['severity'] = 'danger'
            render_form( args_dict )
            return

        db = get_connection()
        cur = db.cursor()
        cur.execute("""
            SELECT id, password_salt, password_hash
              FROM users
             WHERE email = %s
               AND is_active = 1
        """, (email,))
        row = cur.fetchone()
        if not row:
            args_dict['message'] = "E-Mail address not found, or not active."
            args_dict['severity'] = 'danger'
            render_form( args_dict )
            db.close()
            return
        # working through here, have the salt/hash, verify and set session
        salt_b64 = row["password_salt"]
        hash_b64 = row["password_hash"]
        if verify_password(password, salt_b64, hash_b64):
            session_id = str(uuid.uuid4())
            cur.execute("UPDATE users SET session_id=%s WHERE id=%s", (session_id, row["id"]))
            db.commit()
            cookie = http.cookies.SimpleCookie()
            cookie["session_id"] = session_id
            cookie["session_id"]["path"] = "/"         # cookie works across all paths
            cookie["session_id"]["httponly"] = True    # cannot be touched by JS

            # Important: headers *before* blank line
            print("Status: 302 Found")
            print(cookie.output())
            print("Location: cpadmin_dash.py")
            print()   # end of headers
            return

            # since we just logged in, offer link to dashboard
            # to_dashbd = f'<a class="alert-link" href="/cgi-bin/cpadmin_dash.py">ASF Alumni Database</a>'
            # args_dict['message'] = f'''
            #     Login successful!<br>
            #     Continue to the { to_dashbd }
            # '''  # Session ID: {session_id}'''
            # args_dict['severity'] = 'success'
            # render_form(args_dict, cookie=cookie)
        else:
            args_dict['message'] = "Invalid E-Mail or Password"
            args_dict['severity'] = 'danger'
            render_form( args_dict )
        db.close()
    else:  # GET request
        # Just render the form, no message
        render_form({})

# --- entry point ---
if __name__ == "__main__":
    main()
