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

/**
 * @file 09.WebSocket.ino
 * @brief Bidirectional WebSocket echo (RFC 6455) via on_ws().
 *
 * Registers a WebSocket endpoint at /ws: each text frame the browser sends is
 * echoed back with an "echo: " prefix. The incoming message is read from
 * ws_pool[ws_id].buf (null-terminated). A tiny test page is served at /.
 *
 * Flash, open Serial @ 115200 for the IP, then browse to http://<ip>/ and type.
 */

#include "dwserver.h"
#include "network_drivers/physical/physical.h"
#include <WiFi.h>

static const char *SSID = "YOUR_SSID";
static const char *PASSWORD = "YOUR_PASSWORD";

DetWebServer server;

static const char PAGE[] = "<!doctype html><meta charset=utf-8><title>WS echo</title>"
                           "<input id=i autofocus><pre id=o></pre><script>"
                           "var w=new WebSocket('ws://'+location.host+'/ws');"
                           "w.onmessage=function(e){o.textContent+=e.data+'\\n'};"
                           "i.onkeydown=function(e){if(e.key=='Enter'){w.send(i.value);i.value=''}}</script>";

void ws_connect(uint8_t ws_id)
{
    server.ws_send_text(ws_id, "connected to /ws - type something");
}

void ws_message(uint8_t ws_id)
{
    char out[WS_FRAME_SIZE + 8];
    snprintf(out, sizeof(out), "echo: %s", (const char *)ws_pool[ws_id].buf);
    server.ws_send_text(ws_id, out);
}

void ws_close(uint8_t ws_id)
{
    (void)ws_id;
}

void setup()
{
    Serial.begin(115200);
    init_wifi_physical(SSID, PASSWORD);
    Serial.print("Connecting to WiFi");
    while (!wifi_ready())
    {
        delay(250);
        Serial.print('.');
    }
    Serial.print("\nIP: ");
    Serial.println(WiFi.localIP());
    WiFi.setSleep(false);

    server.on("/", HTTP_GET, [](uint8_t id, HttpReq *) { server.send(id, 200, "text/html", PAGE); });
    server.on_ws("/ws", ws_connect, ws_message, ws_close);
    server.begin(80);
}

void loop()
{
    server.handle();
}
