#!/usr/bin/env python3
import logging
import os
import socket
import subprocess
import sys
import json
from datetime import date
from pathlib import Path

# Asegura que `helpers` se pueda importar aunque cron ejecute desde otro cwd
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
from helpers.singleton import single_instance
from helpers.db import ejecutar_sp
from helpers.logging_setup import setup_logging, setup_logging_db

ID_PROCESO = int(os.getenv("ID_PROCESO_DESCARGA", 0))

BASE_DIR = Path(__file__).parent
ROOT_DIR = Path(__file__).resolve().parent.parent.parent
SCRIPTS_DIR = BASE_DIR / "scripts_descarga_boletines"
BOLETINES_DIR = ROOT_DIR / "files" / "boletines"
LOGS_DIR = ROOT_DIR / "logs" / "descarga"


def _cargar_schedule():
    config_path = ROOT_DIR / "schedule.json"
    with open(config_path, encoding="utf-8") as f:
        config = json.load(f)
    return [
        (p["script"], p["carpeta"], p["dias"])
        for p in config["provincias"]
        if p.get("activo", True)
    ]


SCHEDULE = _cargar_schedule()


def limpiar_linea(texto):
    return texto.encode("ascii", errors="ignore").decode("ascii").strip()


def run_script(script_name, destino):
    destino.mkdir(parents=True, exist_ok=True)
    script_path = SCRIPTS_DIR / script_name
    logging.info(f"Iniciando {script_name}")

    result = subprocess.run(
        [sys.executable, str(script_path), "--directorio", str(destino)],
        capture_output=True,
        text=True,
    )

    stdout_lines = [limpiar_linea(l) for l in result.stdout.splitlines() if limpiar_linea(l)]
    stderr_lines = [limpiar_linea(l) for l in result.stderr.splitlines() if limpiar_linea(l)]

    for line in stdout_lines:
        logging.debug(f"  [{script_name}] {line}")
    for line in stderr_lines:
        logging.debug(f"  [{script_name}] STDERR: {line}")

    if result.returncode != 0:
        logging.error(f"FALLO {script_name} (codigo {result.returncode})")
        ultimas = stdout_lines[-10:] + [f"STDERR: {l}" for l in stderr_lines]
        for line in ultimas:
            logging.error(f"  >> {line}")
        return False
    else:
        logging.info(f"OK    {script_name}")
        return True


def main():
    hoy = date.today()
    dia = hoy.weekday()
    run_id = setup_logging("descarga")

    logging.info(f"PROCESO_INICIADO | proceso=descarga fecha={hoy}")

    id_log = None
    try:
        result = ejecutar_sp('PRS_iniciar', [
            ID_PROCESO,
            socket.gethostbyname(socket.gethostname()),
            os.getpid(),
            socket.gethostname(),
            12,
            run_id,
        ])
        if result:
            id_log = result[0].get('id_log')
            setup_logging_db(id_log)
    except Exception as e:
        logging.warning(f"PRS_iniciar falló: {e}")

    resultados = {"ok": [], "error": []}

    try:
        if dia >= 5:
            logging.info("Fin de semana, no hay descargas.")
            return

        dias_nombre = ["lunes", "martes", "miércoles", "jueves", "viernes"]
        logging.info(f"Día: {dias_nombre[dia]}")

        pendientes = [(s, c) for s, c, ds in SCHEDULE if dia in ds]
        logging.info(f"Scripts a ejecutar: {len(pendientes)}")

        for script, carpeta in pendientes:
            destino = BOLETINES_DIR / carpeta / "sin_procesar"
            exito = run_script(script, destino)
            provincia = carpeta.replace("_", " ").upper()
            if exito:
                resultados["ok"].append(provincia)
            else:
                resultados["error"].append(provincia)

        logging.info(f"Exitosos  ({len(resultados['ok'])}): {', '.join(resultados['ok']) or 'ninguno'}")
        logging.info(f"Con error ({len(resultados['error'])}): {', '.join(resultados['error']) or 'ninguno'}")
        logging.info("FIN")

    finally:
        if id_log is not None:
            try:
                ejecutar_sp('PRS_finalizar', [
                    id_log,
                    None,
                    len(resultados["ok"]) + len(resultados["error"]),
                    len(resultados["ok"]),
                    len(resultados["error"]),
                ])
            except Exception as e:
                logging.warning(f"PRS_finalizar falló: {e}")


if __name__ == "__main__":
    with single_instance("descarga_edictos"):
        main()

