from flask import Flask, render_template, request, redirect, url_for, session
import uuid
import subprocess
import re
import os
import random
from captcha.image import ImageCaptcha
from waitress import serve
import base64
import configparser
import configparser

# Load from config.ini

config = configparser.ConfigParser()
config.read("../config.ini")
secretkey = config.get("Signup", "secretkey")
captchachars = config.get("Signup", "captchachars")
runport = config.get("Signup", "port")

# Status report

print("HectaMail is starting up...")
print("Your secret key is:", secretkey)
print("Your CAPTCHA allowed characters are:", captchachars)

# Define the allowed pattern for the username

allowed_pattern = r'^[a-zA-Z0-9.]+$'

# Function to generate the CAPTCHA Code

def generate_captcha_text():
#    characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    captcha_text = ''.join(random.choice(captchachars) for i in range(6))
    return captcha_text

# Function to determine if the username is compilent with the regex filter

def is_valid_input(input_string):
    return re.match(allowed_pattern, input_string) is not None

# Initalise Flask

app = Flask(__name__)
app.secret_key = secretkey

# Function to create the email account, in this case using doas for security

def create_email_account(username, password):
    if password and is_valid_input(username):
        try:

            # Create a temporary file to escape the password

            with open("tmp/password.tmp", "w") as file:
                file.write(password)

            # Pass the file through a shell command
            cmd = ["cat", "tmp/password.tmp", "|", "doas", "-u", "maddy", "maddy", "creds", "create", f"{username}@hectabit.org"]

            # Run and determine the result of the shell command
            result = subprocess.run(" ".join(cmd), shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

            # Delete the temporary file
            os.remove("tmp/password.tmp")


            # Check if command executed correctly
            if result.returncode == 0:
                # Command executed successfully
                return True
            else:
                # Handle errors, log them, and return False
                error_message = result.stderr.decode("utf-8")
                print(f"Error creating email account: {error_message}")
                return False
        except Exception as e:
            # Handle exceptions and return False
            print(f"Error creating email account: {str(e)}")
            return False
    else:
        # Something went very wrong if this function triggers
        print(f"Injection Bypass! Very bad!")
        return False

@app.route('/')
def index():
    # Generate a unique token
    unique_token = str(uuid.uuid4())

    # Generate the CAPTCHA for the user
    captcha_text = generate_captcha_text()
    image = ImageCaptcha().generate(captcha_text)

    # Store the CAPTCHA and token in the session
    session['captcha_text'] = captcha_text
    session['unique_token'] = unique_token

    # Encode the image in base64
    image_base64 = base64.b64encode(image.getvalue()).decode('utf-8')

    # Report the CAPTCHA
    print(captcha_text)

    # Pass the CAPTCHA through to index.html
    return render_template('index.html', captcha_image=image_base64, unique_token=unique_token)

@app.route('/api', methods=['POST'])
def register():
    # Get the form data
    username = request.form.get('username')
    password = request.form.get('password')

    # Get the CAPTCHA
    user_captcha = request.form.get('captcha')

    # Get the unique token
    submitted_token = request.form.get('unique_token')

    # Check if the submitted token matches the one in the session
    if submitted_token != session.get('unique_token'):
        # Token mismatch, handle accordingly
        return render_template('expired.html'), 400

    # Generate a new unique token for the next request
    session['unique_token'] = str(uuid.uuid4())

    # Report the user captcha result
    print(user_captcha)

    # Check the regex filter
    if not is_valid_input(username):
        return render_template('num.html'), 400

    # Validate the captcha
    captcha_text = session.get('captcha_text', '')
    print(captcha_text)
    if user_captcha.lower() != captcha_text.lower():
        # CAPTCHA incorrect
        return render_template('captcha_err.html'), 400

    # Attempt to create the email
    if create_email_account(username, password):
        # Email created
        return render_template('ok.html')
    else:
        # Backend error, potentially maddy
        return render_template('err.html'), 500

# Start the web server
if __name__ == '__main__':
    serve(app, host='0.0.0.0', port=runport)
