#!/usr/bin/env python3
import os
import sys
import time
from pathlib import Path

import marko
from marko.ext.gfm import GFM
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

from  log.Logger import *
from hashes.obfuscation.Obfuscator import Obfuscator
from htmlhandler import htmlhandler as Handler

# Use absolute paths
ROOT = Path(os.path.abspath("."))
MARKDOWN_DIR = ROOT / "markdown"
HTML_DIR = ROOT / "html"


# Create markdown parser with table support
markdown_parser = marko.Markdown(extensions=[GFM])
Logger = Logger()

# Global obfuscate flag, default True
obfuscate = True

def render_markdown(md_path: Path):
    """Render a single markdown file to an obfuscated HTML file."""
    try:
        text = md_path.read_text(encoding="utf-8")
    except Exception as e:
        Logger.log_error(f"Could not read {md_path}: {e}")
        return

    html_body = markdown_parser.convert(text)
    
    # Extract title from filename or first H1
    title = md_path.stem
    for line in text.splitlines():
        if line.startswith("# "):
            title = line[2:].strip()
            break
    
    import base64
    import random
    from hashes.hashes import hash_list
    # Create clean HTML structure
    # Pick two different hashes from hash_list
    hash1, hash2 = random.sample(hash_list, 2)

    clean_html = f"""<!doctype html>
<html lang="en" style="height:100%; margin:0;">
<head>
    <meta charset="utf-8">
    <title>{title}</title>
    <link rel="stylesheet" href="../css/main.css">
    <link rel="icon" type="image/x-icon" href="../css/favicon/favicon.ico">
    <script src="../js/post/normal.js"></script>
</head>
<body style="display:flex; flex-direction:column; min-height:100%; margin:0;">
    <main class="container" style="flex:1;">
        <h1 onclick="window.location.href='/'" style="cursor:pointer; display:flex; align-items:center; gap:8px; font-size:1.5em; margin:0;">
            <img src="../css/icons/back.png" width="32" height="32" alt="Back" style="display:block;" />
                {title}
        </h1>
        <img src="../css/icons/written.png" width="32" height="32" alt="write_img" loading="lazy" style="vertical-align: middle;padding-left:12px; padding-left:40px;" />
        <div class="meta" style="display: inline;">Written @{time.asctime(time.localtime())}</div>
        <hr style="margin:10px 0;" />
        {html_body}
    </main>

    <footer style="margin-top:auto; width:100%;">
        <hr style="margin:10px 0;" />
            <img src="../css/icons/date.png" width="16" height="16" alt="date" loading="lazy" style="vertical-align: middle;" />
            {time.strftime("%Y-%m-%d %H:%M:%S")}<br/>
        <img src="../css/icons/magnifier.png" width="16" height="16" alt="Hash1" loading="lazy" style="display:inline; vertical-align:middle;" />
        Hash 1 (<b>UTF-8</b>)<i>:{base64.b64encode(hash1.encode("utf-8")).decode("utf-8")}</i><br />
        <img src="../css/icons/magnifier.png" width="16" height="16" alt="Hash2" loading="lazy" style="display:inline; vertical-align:middle;" />
        Hash 2 (<b>Windows-1252</b>)<i>:{base64.b64encode(hash2.encode("windows-1252")).decode("windows-1252")}</i><br />
    </footer>
</body>
</html>"""

    
    # Obfuscate the HTML for browser output
    obfuscated_html = Obfuscator.obfuscate_html(clean_html)
    
    # Ensure html directory exists
    HTML_DIR.mkdir(exist_ok=True)
    
    # Maintain relative directory structure in html/
    relative_path = md_path.relative_to(MARKDOWN_DIR)
    out_path = HTML_DIR / relative_path.with_suffix(".html")
    
    # Create parent directories if needed
    out_path.parent.mkdir(parents=True, exist_ok=True)


    if obfuscate:
        out_path.write_text(obfuscated_html, encoding="utf-8")
    else:
        out_path.write_text(clean_html, encoding="utf-8")

    Logger.log_debug(f"Rendered: {md_path} -> {out_path}")

def remove_html(md_path: Path):
    relative_path = md_path.relative_to(MARKDOWN_DIR)
    out_path = HTML_DIR / relative_path.with_suffix(".html")
    if out_path.exists():
        out_path.unlink()
        Logger.log_debug(f"Removed: {out_path}")


def initial_scan(markdown_dir: Path):
    Logger.log_info(f"Starting initial scan of markdown files in {markdown_dir}...")
    for md in markdown_dir.rglob("*.md"):
        render_markdown(md)


if __name__ == "__main__":
    if not MARKDOWN_DIR.exists():
        alt_root = ROOT / "PyPost"
        if alt_root.exists() and alt_root.is_dir():
            Logger.log_warning(f"Default 'markdown' directory not found, switching ROOT to: {alt_root}")
            ROOT = alt_root
            MARKDOWN_DIR = ROOT / "markdown"
            HTML_DIR = ROOT / "html"
        else:
            Logger.log_error(f"Markdown directory not found: {MARKDOWN_DIR}")
            Logger.log_warning("Please create a 'markdown' directory or use a 'PyPost' directory with one inside it.")
            sys.exit(1)
    import argparse

    parser = argparse.ArgumentParser(description="Monitor markdown directory and convert to HTML.")

    # This stores True when passed, but means "no obfuscation"
    parser.add_argument(
        "--no-obfuscate",
        action="store_false",
        help="Disable HTML obfuscation."
    )

    args = parser.parse_args()

    # Invert it to get the obfuscate flag
    obfuscate = not args.no_obfuscate

    Logger.log_obfuscation_info(f"Obfuscation is {'enabled' if obfuscate else 'disabled'}", obfuscate)

    initial_scan(MARKDOWN_DIR)
    event_handler = Handler()
    observer = Observer()
    observer.schedule(event_handler, str(MARKDOWN_DIR), recursive=True)
    observer.start()
    Logger.log_info(f"Started monitoring {MARKDOWN_DIR} for changes.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()