from flask import Flask, render_template, request, jsonify, redirect
import time
import os
import ssl
import subprocess
from pathlib import Path
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
import datetime

app = Flask(__name__)

host_ip = '127.0.0.1'
host_port = 5000
template_path = 'templates'
static_path = 'static'
routes_data = {}
protocol = "http"

class RapidHost:

    # =========================
    # Configuração básica
    # =========================

    def hostIP(ip):
        global host_ip
        host_ip = ip

    def hostPort(port):
        global host_port
        host_port = port

    def setTemplatePath(path):
        global template_path
        template_path = path
        app.template_folder = template_path

    def setStaticPath(path):
        global static_path
        static_path = path
        app.static_folder = static_path

    def setProtocol(proto):
        global protocol
        protocol = proto.lower()

    # =========================
    # HTTPS automático
    # =========================

    def _generate_ssl():
     cert_folder = Path("rapidhost_ssl")
     cert_folder.mkdir(exist_ok=True)
 
     cert_file = cert_folder / "cert.pem"
     key_file = cert_folder / "key.pem"
 
     if cert_file.exists() and key_file.exists():
         return str(cert_file), str(key_file)
 
     print("🔐 Gerando certificado SSL interno...")
 
     key = rsa.generate_private_key(
         public_exponent=65537,
         key_size=2048,
         backend=default_backend()
     )
 
     subject = issuer = x509.Name([
         x509.NameAttribute(NameOID.COUNTRY_NAME, u"BR"),
         x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Sao Paulo"),
         x509.NameAttribute(NameOID.LOCALITY_NAME, u"Sao Jose dos Campos"),
         x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"RapidHost"),
         x509.NameAttribute(NameOID.COMMON_NAME, u"localhost"),
     ])
 
     cert = (
         x509.CertificateBuilder()
         .subject_name(subject)
         .issuer_name(issuer)
         .public_key(key.public_key())
         .serial_number(x509.random_serial_number())
         .not_valid_before(datetime.datetime.utcnow())
         .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365))
         .sign(key, hashes.SHA256(), default_backend())
     )
 
     with open(cert_file, "wb") as f:
         f.write(cert.public_bytes(serialization.Encoding.PEM))
 
     with open(key_file, "wb") as f:
         f.write(
             key.private_bytes(
                 encoding=serialization.Encoding.PEM,
                 format=serialization.PrivateFormat.TraditionalOpenSSL,
                 encryption_algorithm=serialization.NoEncryption(),
             )
         )
 
     return str(cert_file), str(key_file)
     # =========================
     # Rotas dinâmicas
     # =========================
 
    def create_route(route_name, returnMessage):

        def route_function(route_name=route_name, returnMessage=returnMessage):

            if request.method == 'POST':
                data = request.form.to_dict()
                routes_data[route_name] = data

                if returnMessage.startswith("/"):
                    return redirect(returnMessage, code=302)

                if returnMessage.startswith("http://") or returnMessage.startswith("https://"):
                    return redirect(returnMessage, code=302)

                return returnMessage, 200

            return jsonify(routes_data.get(route_name, {}))

        app.add_url_rule(
            f'/{route_name}',
            endpoint=f'route_{route_name}',
            view_func=route_function,
            methods=['GET', 'POST']
        )

    def GetfromRoute(route_name, info=""):
        data = routes_data.get(route_name, {})
        return data if info == "" else data.get(info, "")

    # =========================
    # Host principal
    # =========================

    def hostSite(*pages, information):

        app.template_folder = template_path
        app.static_folder = static_path

        for page in pages:
            route = '/' + page.split('.')[0] if page != 'index.html' else '/'

            def render_specific_page(page=page):
                return render_template(page, info=information)

            app.add_url_rule(
                route,
                endpoint=f"page_{page}",
                view_func=render_specific_page
            )

        if protocol == "https":
            cert, key = RapidHost._generate_ssl()
            print(f"🚀 Servidor rodando em HTTPS → https://{host_ip}:{host_port}")
            app.run(host=host_ip, port=host_port, debug=True, ssl_context=(cert, key))
        else:
            print(f"🚀 Servidor rodando em HTTP → http://{host_ip}:{host_port}")
            app.run(host=host_ip, port=host_port, debug=True)