// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
// SPDX-License-Identifier: AGPL-3.0-or-later

/**
 * @file syslog.h
 * @brief Zero-heap RFC 5424 syslog client over UDP.
 *
 * Ships device log lines to a remote syslog server as RFC 5424 UDP datagrams via
 * the transport-layer UDP service (det_udp_sendto). Split, like the other
 * network services, into a pure host-testable formatter and an ESP32-only send:
 *
 *  - syslog_format() builds one RFC 5424 line into a caller buffer (no sockets,
 *    no heap) - unit-tested on the host (env:native_syslog).
 *  - syslog_log() formats into a static scratch buffer and sends it to the
 *    configured server (a no-op stub off-target).
 *
 * Emitted line: `<PRI>1 - HOSTNAME APP-NAME - - - MSG`, where PRI = facility*8 +
 * severity. TIMESTAMP/PROCID/MSGID/STRUCTURED-DATA are the RFC 5424 NILVALUE
 * ("-"); the server stamps its own receipt time. Strings are copied into fixed
 * BSS buffers at init, so nothing must outlive the call.
 */

#ifndef DETERMINISTICESPASYNCWEBSERVER_SYSLOG_H
#define DETERMINISTICESPASYNCWEBSERVER_SYSLOG_H

#include "ServerConfig.h"
#include <stddef.h>
#include <stdint.h>

#if DETWS_ENABLE_SYSLOG

/** @brief RFC 5424 §6.2.1 severity levels (numerically lower = more severe). */
enum SyslogSeverity
{
    SYSLOG_EMERG = 0,   ///< system is unusable
    SYSLOG_ALERT = 1,   ///< action must be taken immediately
    SYSLOG_CRIT = 2,    ///< critical conditions
    SYSLOG_ERR = 3,     ///< error conditions
    SYSLOG_WARNING = 4, ///< warning conditions
    SYSLOG_NOTICE = 5,  ///< normal but significant
    SYSLOG_INFO = 6,    ///< informational
    SYSLOG_DEBUG = 7,   ///< debug-level messages
};

/** @brief Common RFC 5424 §6.2.1 facilities (the default is LOCAL0). */
enum SyslogFacility
{
    SYSLOG_FAC_USER = 1,    ///< user-level messages
    SYSLOG_FAC_DAEMON = 3,  ///< system daemons
    SYSLOG_FAC_LOCAL0 = 16, ///< local use 0 (default)
    SYSLOG_FAC_LOCAL1 = 17,
    SYSLOG_FAC_LOCAL7 = 23,
};

/**
 * @brief Configure the syslog client (call after WiFi is up).
 *
 * @param server_ip dotted-quad IPv4 of the syslog server (e.g. "192.168.1.10").
 * @param port      server UDP port (514 is the IANA syslog port).
 * @param hostname  this device's HOSTNAME field (copied; pass nullptr/"" for "-").
 * @param appname   APP-NAME field (copied; pass nullptr/"" for "-").
 * @param facility  syslog facility (default LOCAL0).
 */
void syslog_init(const char *server_ip, uint16_t port, const char *hostname, const char *appname,
                 int facility = SYSLOG_FAC_LOCAL0);

/**
 * @brief Format one RFC 5424 line into @p out (host-testable; no sockets/heap).
 *
 * @return number of bytes written (excl. NUL), or 0 if it would not fit @p cap.
 */
size_t syslog_format(char *out, size_t cap, int facility, int severity, const char *hostname, const char *appname,
                     const char *msg);

/**
 * @brief Format @p msg at @p severity and send it to the configured server.
 *
 * @return true if the datagram was queued; false if not yet configured, the line
 *         overflowed DETWS_SYSLOG_MSG_MAX, or the send failed (host build).
 */
bool syslog_log(int severity, const char *msg);

#endif // DETWS_ENABLE_SYSLOG

#endif // DETERMINISTICESPASYNCWEBSERVER_SYSLOG_H
