"""
@RAG_CONTEXT
{
  "archivo": "indexador_ocr.py",
  "lineas": 71,
  "tokens_estimados": 650,
  "hash_contenido": "7d9d2e281813efb117f71e5168ef26fbde01f8f0ebda01f3d249ff5644aea4fe",
  "creacion": "2026-03-13",
  "modificacion": "2026-03-13",
  "tags": [
    "PIL",
    "Image",
    "os",
    "datetime"
  ],
  "descripcion_corta": "Indexador OCR para imágenes y PDFs con seguimiento de cambios",
  "descripcion_larga": "Script Python que indexa archivos de imagen (JPG, PNG) y PDFs mediante OCR, extrayendo texto con Tesseract (imágenes) y pdftotext (PDFs). Mantiene un índice JSON con hash MD5 para detectar cambios, excluye directorios en blacklist, y guarda automáticamente cada 5 archivos procesados. Requiere ruta de motor OCR como argumento y configuración en config.json."
}
"""
#!/usr/bin/env python3
import os, json, hashlib, subprocess, sys
from datetime import datetime
from PIL import Image

if len(sys.argv) < 2:
    print("Error: Se requiere la ruta del motor (.ocr-indexer)")
    sys.exit(1)

RUTA_MOTOR = sys.argv[1]
CONFIG_PATH = os.path.join(RUTA_MOTOR, "config.json")
INDEX_PATH = os.path.join(RUTA_MOTOR, "index.json")

# Cargar Configuración Local
with open(CONFIG_PATH, 'r') as f:
    config = json.load(f)

RAIZ_A_ESCANEAR = config['root']
BLACKLIST = config.get('blacklist', [])
AUTOGUARDADO = 5

def obtener_hash(ruta):
    hasher = hashlib.md5()
    try:
        with open(ruta, 'rb') as f:
            for chunk in iter(lambda: f.read(65536), b""):
                hasher.update(chunk)
        return hasher.hexdigest()
    except: return None

def extraer_texto(ruta, ext):
    try:
        if ext == 'pdf':
            return subprocess.run(["/usr/bin/pdftotext", ruta, "-"], capture_output=True, text=True).stdout.strip()
        else:
            return subprocess.run(["/usr/bin/tesseract", ruta, "stdout", "-l", "spa"], capture_output=True, text=True).stdout.strip()
    except: return ""

# Cargar o crear índice
indice = {}
if os.path.exists(INDEX_PATH) and os.path.getsize(INDEX_PATH) > 0:
    with open(INDEX_PATH, 'r', encoding='utf-8') as f:
        indice = json.load(f)

cambios = 0
for root, dirs, files in os.walk(RAIZ_A_ESCANEAR):
    if any(item in root for item in BLACKLIST) or ".ocr-indexer" in root:
        continue
    
    for file in files:
        ext = file.lower().split('.')[-1]
        if ext in ['jpg', 'jpeg', 'png', 'pdf']:
            ruta_completa = os.path.join(root, file)
            h = obtener_hash(ruta_completa)
            if not h: continue
            
            if ruta_completa not in indice or indice[ruta_completa].get('integridad', {}).get('hash_md5') != h:
                print(f"Procesando: {file}")
                indice[ruta_completa] = {
                    "archivo": {"nombre": os.path.splitext(file)[0], "extension": ext, "directorio": root},
                    "fechas": {"indexacion": datetime.now().isoformat()},
                    "integridad": {"hash_md5": h},
                    "contenido": {"texto_ocr": extraer_texto(ruta_completa, ext)}
                }
                cambios += 1
                if cambios % AUTOGUARDADO == 0:
                    with open(INDEX_PATH, 'w', encoding='utf-8') as f:
                        json.dump(indice, f, indent=4, ensure_ascii=False)

with open(INDEX_PATH, 'w', encoding='utf-8') as f:
    json.dump(indice, f, indent=4, ensure_ascii=False)
