import os
import sys
import threading
import subprocess
from http.server import BaseHTTPRequestHandler, HTTPServer
import mimetypes
from functools import lru_cache
from jsmin import jsmin  # pip install jsmin

from log.Logger import *
logger = Logger()
import PyPost

PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
HTML_DIR = os.path.join(PROJECT_ROOT, "html")
BASE_FILE = os.path.join(HTML_DIR, "base", "index.html")

def get_html_files(directory=HTML_DIR):
    html_files = []
    for entry in os.listdir(directory):
        full_path = os.path.join(directory, entry)
        if os.path.isfile(full_path) and entry.endswith(".html"):
            html_files.append(entry)
    return html_files

def build_index_page():
    with open(BASE_FILE, "r", encoding="utf-8") as f:
        base_html = f.read()
    html_files = get_html_files(HTML_DIR)
    links = "\n".join(f'<li><a href="/html/{fname}">{fname}</a></li>' for fname in html_files)
    content = f"<ul>{links}</ul>"
    # Insert footer after content
    full_content = content + index_footer()
    return base_html.replace("<!-- CONTENT -->", full_content)

import base64
import random

from hashes.hashes import hash_list

@lru_cache
def index_footer():
    h1 = random.choice(hash_list)
    # Ensure h2 is different from h1
    h2_candidates = [h for h in hash_list if h != h1]
    h2 = random.choice(h2_candidates) if h2_candidates else h1

    return f"""
<footer style="
  position: absolute;
  bottom: 0;
  width: 100%;
  ">
  <hr style="border: 1px solid #ccc;" />
  <p>
    Server-Time (CET): <i>{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}</i><br />
    Hash 1 (<b>UTF-8</b>)<i>:{base64.b64encode(h1.encode("utf-8")).decode("utf-8")}</i><br />
    Hash 2 (<b>Windows-1252</b>)<i>:{base64.b64encode(h2.encode("windows-1252")).decode("windows-1252")}</i><br />
  </p>
</footer>
"""

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        req_path = self.path.lstrip("/")
        if req_path == "" or req_path == "index.html":
            content = build_index_page()
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(content.encode("utf-8"))
            return

        file_path = os.path.normpath(os.path.join(PROJECT_ROOT, req_path))
        if not file_path.startswith(PROJECT_ROOT):
            self.send_response(403)
            self.end_headers()
            self.wfile.write(b"403 - Forbidden")
            return

        if os.path.isfile(file_path):
            mime_type, _ = mimetypes.guess_type(file_path)
            if mime_type is None:
                mime_type = "application/octet-stream"

            with open(file_path, "rb") as f:
                content = f.read()

            # Obfuscate JS on the fly
            if mime_type == "application/javascript" or file_path.endswith(".js"):
                try:
                    content = jsmin(content.decode("utf-8")).encode("utf-8")
                except Exception as e:
                    logger.log_error(f"Error minifying JS file {file_path}: {e}")

            self.send_response(200)
            self.send_header("Content-type", mime_type)
            self.end_headers()
            self.wfile.write(content)
            return

        self.send_response(404)
        self.end_headers()
        self.wfile.write(b"404 - Not Found")

def run_pypost():
    """Run PyPost.py in a separate process."""
    script = os.path.join(PROJECT_ROOT, "PyPost.py")
    subprocess.run([sys.executable, script])

if __name__ == "__main__":
    try:
        threading.Thread(target=run_pypost, daemon=True).start()
        logger.log_debug("Started PyPost.py in background watcher thread.")

        server_address = ("localhost", 8000)
        httpd = HTTPServer(server_address, MyHandler)
        logger.log_info(f"Serving on http://{server_address[0]}:{server_address[1]}")
        httpd.serve_forever()
    except (Exception, KeyboardInterrupt) as e:
        logger.log_info(f"Shutting down server.\n Reason: {e}")
        httpd.server_close()

