#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Consulta un SAI Delta InsightPower por SNMP.
Pide los OIDs en lotes dentro del mismo paquete: 2 viajes en vez de 16.
Compatible Python 3.5 (sin f-strings).
"""

import subprocess
import sys

# El ORDEN importa: snmpget devuelve los valores en el mismo orden pedido.
CLAVES = [
    ("modelo",          "1.3.6.1.2.1.33.1.1.2.0"),
    ("nombre",          "1.3.6.1.2.1.33.1.1.5.0"),
    ("fuente",          "1.3.6.1.2.1.33.1.4.1.0"),
    ("estado_bat",      "1.3.6.1.2.1.33.1.2.1.0"),
    ("segs_en_bateria", "1.3.6.1.2.1.33.1.2.2.0"),
    ("minutos_rest",    "1.3.6.1.2.1.33.1.2.3.0"),
    ("carga_bat_pct",   "1.3.6.1.2.1.33.1.2.4.0"),
    ("tension_bat",     "1.3.6.1.2.1.33.1.2.5.0"),
    ("temp_bat",        "1.3.6.1.2.1.33.1.2.7.0"),
    ("fallos_red",      "1.3.6.1.2.1.33.1.3.1.0"),
    ("v_entrada",       "1.3.6.1.2.1.33.1.3.3.1.3.1"),
    ("f_entrada",       "1.3.6.1.2.1.33.1.3.3.1.2.1"),
    ("v_salida",        "1.3.6.1.2.1.33.1.4.4.1.2.1"),
    ("carga_pct",       "1.3.6.1.2.1.33.1.4.4.1.5.1"),
    ("potencia_w",      "1.3.6.1.2.1.33.1.4.4.1.4.1"),
    ("alarmas",         "1.3.6.1.2.1.33.1.6.1.0"),
]

FUENTE = {
    1: "Otra", 2: "Sin salida", 3: "Red (normal)", 4: "Bypass",
    5: "BATERIA", 6: "Booster", 7: "Reducer",
}

ESTADO_BAT = {
    1: "Desconocido", 2: "Normal", 3: "BAJA", 4: "AGOTADA",
}

DECIMAS = ("tension_bat", "f_entrada")

LOTE = 8       # OIDs por paquete
TIMEOUT = 3    # segundos
REINTENTOS = 1


def _snmpget_lote(host, puerto, community, oids):
    """Un solo snmpget con varios OIDs. Devuelve lista de strings o None."""
    destino = "{0}:{1}".format(host, puerto)
    cmd = ["snmpget", "-v2c", "-c", community, "-Oqv",
           "-t", str(TIMEOUT), "-r", str(REINTENTOS), destino] + list(oids)
    try:
        salida = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    except (subprocess.CalledProcessError, OSError):
        return None

    lineas = salida.decode("utf-8", "replace").splitlines()
    if len(lineas) != len(oids):
        return None

    limpias = []
    for linea in lineas:
        texto = linea.strip().strip('"')
        if not texto or "No Such" in texto or "Timeout" in texto:
            limpias.append(None)
        else:
            limpias.append(texto)
    return limpias


def leer_sai(host, puerto, community):
    datos = {"host": host, "puerto": puerto, "ok": False}

    crudos = {}
    for i in range(0, len(CLAVES), LOTE):
        trozo = CLAVES[i:i + LOTE]
        valores = _snmpget_lote(host, puerto, community,
                                [oid for _c, oid in trozo])
        if valores is None:
            valores = [None] * len(trozo)
        for (clave, _oid), valor in zip(trozo, valores):
            crudos[clave] = valor

    for clave, _oid in CLAVES:
        crudo = crudos.get(clave)
        if crudo is None:
            datos[clave] = None
            continue
        try:
            valor = int(crudo)
            if clave in DECIMAS:
                valor = valor / 10.0
        except ValueError:
            valor = crudo
        datos[clave] = valor

    datos["ok"] = datos.get("fuente") is not None
    datos["fuente_txt"] = FUENTE.get(datos.get("fuente"), "?")
    datos["estado_bat_txt"] = ESTADO_BAT.get(datos.get("estado_bat"), "?")
    datos["en_bateria"] = (datos.get("fuente") == 5)
    datos["en_bypass"] = (datos.get("fuente") == 4)
    datos["bat_critica"] = (datos.get("estado_bat") in (3, 4))
    return datos


if __name__ == "__main__":
    if len(sys.argv) < 4:
        print("uso: delta_status.py <host> <puerto> <community> [etiqueta]")
        sys.exit(1)
    from formato import formatear_telegram
    etiqueta = sys.argv[4] if len(sys.argv) > 4 else None
    datos = leer_sai(sys.argv[1], int(sys.argv[2]), sys.argv[3])
    print(formatear_telegram(datos, etiqueta))
    sys.exit(0 if datos["ok"] else 1)
