#include <string.h>
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "esp_log.h"
#include "dns_server.h"


static const char *TAG = "DNS";

#define DNS_PORT 53

void start_dns_server(void) {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) {
        ESP_LOGE(TAG, "❌ Falha ao criar socket DNS");
        return;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(DNS_PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        ESP_LOGE(TAG, "❌ Falha ao bind socket DNS");
        close(sock);
        return;
    }

    ESP_LOGI(TAG, "✅ DNS captive portal iniciado na porta %d", DNS_PORT);

    while (1) {
        char buf[512];
        struct sockaddr_in source_addr;
        socklen_t socklen = sizeof(source_addr);

        int len = recvfrom(sock, buf, sizeof(buf), 0,
                           (struct sockaddr*)&source_addr, &socklen);

        if (len > 0) {
            // resposta simples: sempre devolve 192.168.4.1
            buf[2] |= 0x80; // resposta
            buf[3] |= 0x80; // autoritativo
            buf[7] = 1;     // 1 resposta

            // append resposta A 192.168.4.1
            buf[len++] = 0xC0; buf[len++] = 0x0C;
            buf[len++] = 0x00; buf[len++] = 0x01; // type A
            buf[len++] = 0x00; buf[len++] = 0x01; // class IN
            buf[len++] = 0x00; buf[len++] = 0x00;
            buf[len++] = 0x00; buf[len++] = 0x3C; // TTL 60s
            buf[len++] = 0x00; buf[len++] = 0x04; // data length
            buf[len++] = 192; buf[len++] = 168;
            buf[len++] = 4;   buf[len++] = 1;

            sendto(sock, buf, len, 0,
                   (struct sockaddr*)&source_addr, socklen);
        }
    }
}
