import os
import re
import time
import traceback
import psutil
import fitz
from datetime import datetime

import sys
# Ensure app modules can be imported
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
from app.services.parser.hybrid_parser import HybridParser

# ==============================================================================
# KONFIGURASI DIREKTORI OUTPUT
# ==============================================================================
BASE_OUTPUT_DIR = "archive/Testing-Pipeline/benchmark-parsing"
OUTPUT_PARSING_DIR = os.path.join(BASE_OUTPUT_DIR, "Output-Parsing")
LOG_ERROR_DIR = os.path.join(BASE_OUTPUT_DIR, "Log-Error")
PERFORM_MATRIX_DIR = os.path.join(BASE_OUTPUT_DIR, "Perform-Matrix")

MATRIX_FILE = os.path.join(PERFORM_MATRIX_DIR, "performance_matrix_parsing.md")
ERROR_LOG_FILE = os.path.join(LOG_ERROR_DIR, "parsing_errors.log")

TARGET_PDF = "Literature/Proses Pembuatan Pupuk Kompos dan Penggunaan Pupuk Kompos  di TPS 3R.pdf"
#TARGET_PDF = "Literature/PaperQA Retrieval-Augmented Generative Agent for Scientific Research.pdf"
#TARGET_PDF = "Literature/Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.pdf"  # IGNORE - Ganti dengan file PDF yang ingin diuji
#TARGET_PDF = "Literature/Reviving Life on the Edge Joint Score-Based Graph Generation of Rich Edge Attributes.pdf"
#TARGET_PDF = "Literature/SemanticGraph2Vec Semantic graph embedding for text representation.pdf"
#TARGET_PDF = "Literature/Sistem Budidaya Ikan Lele (Clarias sp.) dalam Kolam Terpal dengan.pdf"
#TARGET_PDF = "Literature/The Hybrid Multimodal Graph Index (HMGI): A ComprehensiveFramework for Integrated Relational and Vector Search.pdf"

def ensure_dirs():
    """Memastikan semua folder output, log, dan matriks tersedia."""
    os.makedirs(OUTPUT_PARSING_DIR, exist_ok=True)
    os.makedirs(LOG_ERROR_DIR, exist_ok=True)
    os.makedirs(PERFORM_MATRIX_DIR, exist_ok=True)

def sanitize_filename(filename: str) -> str:
    """Membersihkan nama file dari spasi dan karakter khusus dengan underscore."""
    base_name = os.path.basename(filename)
    name_without_ext = os.path.splitext(base_name)[0]
    clean_name = re.sub(r'[^a-zA-Z0-9]', '_', name_without_ext)
    clean_name = re.sub(r'_+', '_', clean_name).strip('_')
    return clean_name

def append_to_matrix(timestamp, doc_name, pages, text_pgs, ocr_pgs, peak_ram, peak_cpu, total_time, output_length, ocr_timeouts, status, note=""):
    """Menambahkan baris baru ke file matriks performa secara append."""
    is_new_file = not os.path.exists(MATRIX_FILE)
    
    with open(MATRIX_FILE, "a", encoding="utf-8") as f:
        # Tulis Header jika file belum ada
        if is_new_file:
            f.write("| Timestamp | Document | Pages | Text Pgs | OCR Pgs | Peak RAM (MB) | Peak CPU (%) | Total Time (s) | Output Length | OCR Timeouts | Status | Note |\n")
            f.write("| :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- | :--- |\n")
        
        # Pemotongan panjang nama dokumen maksimal 45 karakter
        short_name = (doc_name[:45] + '...') if len(doc_name) > 48 else doc_name
        
        row = f"| {timestamp} | {short_name} | {pages} | {text_pgs} | {ocr_pgs} | {peak_ram} | {peak_cpu} | {total_time:.2f} | {output_length} | {ocr_timeouts} | {status} | {note} |\n"
        f.write(row)

def append_to_error_log(doc_name, error_exc):
    """Menulis detail error ke file log (Plain Text) secara append."""
    with open(ERROR_LOG_FILE, "a", encoding="utf-8") as f:
        f.write("======================================================================\n")
        f.write(f"TIMESTAMP : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"FILE      : {doc_name}\n")
        f.write(f"ERROR     : {type(error_exc).__name__}\n")
        f.write("DETAILS   :\n")
        f.write(traceback.format_exc())
        f.write("======================================================================\n\n")

if __name__ == "__main__":
    ensure_dirs()
    print("Fase 1: Setup direktori dan fungsi helper berhasil diinisialisasi.")
    
    print(f"==== MEMULAI BENCHMARK PARSING ====")
    print(f"Target: {TARGET_PDF}\n")
    
    if not os.path.exists(TARGET_PDF):
        print(f"Error: File '{TARGET_PDF}' tidak ditemukan!")
        sys.exit(1)

    doc_name = os.path.basename(TARGET_PDF)
    sanitized_name = sanitize_filename(doc_name)
    output_md_path = os.path.join(OUTPUT_PARSING_DIR, f"{sanitized_name}_parsed.md")
    
    total_pages = 0
    try:
        _doc = fitz.open(TARGET_PDF)
        total_pages = len(_doc)
        _doc.close()
    except Exception as e:
        print(f"Warning: Gagal membaca jumlah halaman via PyMuPDF: {e}")
    
    parser = HybridParser()
    print(f"Memproses {total_pages} halaman...")
    
    process = psutil.Process()
    # Initialize CPU measurement
    process.cpu_percent(interval=None)
    start_ram_bytes = process.memory_info().rss
    start_time = time.time()
    
    raw_markdown = None
    status = ""
    note = "-"
    output_length = 0
    
    try:
        raw_markdown = parser.parse_pdf(TARGET_PDF)
        
        if raw_markdown and len(raw_markdown.strip()) > 0:
            status = "✅ Success"
            output_length = len(raw_markdown)
            
            with open(output_md_path, "w", encoding="utf-8") as f:
                f.write(raw_markdown)
            print(f"Parsing selesai! Hasil disimpan ke: {output_md_path}")
        else:
            status = "⚠️ Warning"
            note = "Output kosong"
            print("Parsing selesai, tapi output kosong.")
            
    except Exception as e:
        status = "❌ Failed"
        note = "Lihat log"
        print(f"Parsing gagal: {type(e).__name__} - {e}")
        append_to_error_log(doc_name, e)
    
    total_time = time.time() - start_time
    
    # Calculate peak RAM roughly by taking the end reading, 
    # since we can't easily poll continuously without threading.
    end_ram_bytes = process.memory_info().rss
    peak_ram_mb = max(start_ram_bytes, end_ram_bytes) / (1024 * 1024)
    peak_cpu_percent = process.cpu_percent(interval=None)
    
    current_timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    
    append_to_matrix(
        timestamp=current_timestamp,
        doc_name=doc_name,
        pages=total_pages,
        text_pgs="N/A",
        ocr_pgs="N/A",
        peak_ram=f"{peak_ram_mb:.1f}",
        peak_cpu=f"{peak_cpu_percent:.1f}",
        total_time=total_time,
        output_length=output_length,
        ocr_timeouts="N/A",
        status=status,
        note=note
    )
    print(f"Log performa ditambahkan ke: {MATRIX_FILE}")
