// lora_rx.cpp — LR1121 receive test
// Usage: sudo ./lora_rx [-v] [--433|--868|--24|freq_hz] [--reset]
//   -v       verbose step labels (shows exactly where init hangs)
//   --433    433.05 MHz (default)
//   --868    868 MHz
//   --24     2403 MHz
//   freq_hz  any raw frequency in Hz
//   --reset  send Reboot(app) to escape bootloader, print fw before/after, exit
//
// TX and RX must use identical SF/BW/CR/freq settings.
// Requires SPI: sudo raspi-config → Interfaces → SPI → Yes → reboot
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "lr1121_malnus.hpp"

int main(int argc, char **argv)
{
    lr1121::Config cfg;
    cfg.verbose  = false;
    cfg.pa_sel   = 0x01;
    cfg.tx_dbm   = 14;
    cfg.sf       = 0x07;  // SF7
    cfg.bw       = 0x04;  // 125 kHz
    cfg.cr       = 0x01;  // CR 4/5
    bool do_reset = false;

    for (int i = 1; i < argc; ++i) {
        if      (std::strcmp(argv[i], "-v")      == 0) cfg.verbose = true;
        else if (std::strcmp(argv[i], "--433")   == 0) cfg.freq_hz = lr1121::FREQ_433;
        else if (std::strcmp(argv[i], "--868")   == 0) cfg.freq_hz = lr1121::FREQ_868;
        else if (std::strcmp(argv[i], "--24")    == 0 ||
                 std::strcmp(argv[i], "--2g4")   == 0) cfg.freq_hz = lr1121::FREQ_2400;
        else if (std::strcmp(argv[i], "--reset") == 0) do_reset = true;
        else cfg.freq_hz = (uint32_t)std::strtoul(argv[i], nullptr, 10);
    }

    std::printf("lora_rx: %u Hz  SF%u  BW=0x%02X%s\n",
                cfg.freq_hz, cfg.sf, cfg.bw,
                cfg.verbose ? "  [verbose]" : "");

    if (do_reset) {
        cfg.verbose = true;
        lr1121::Radio radio;
        if (!radio.beginRaw(cfg)) {
            std::fprintf(stderr, "ERROR: cannot open SPI/GPIO\n");
            return 1;
        }
        auto v1 = radio.getVersion();
        std::printf("before reboot: hw=0x%02X type=0x%02X fw=0x%02X%02X\n",
                    v1.hw, v1.type, v1.fw_hi, v1.fw_lo);
        std::printf("sending Reboot(app)...\n");
        radio.reboot(false);
        auto v2 = radio.getVersion();
        std::printf("after  reboot: hw=0x%02X type=0x%02X fw=0x%02X%02X\n",
                    v2.hw, v2.type, v2.fw_hi, v2.fw_lo);
        if (v2.fw_hi >= 0x02)
            std::printf("OK — application firmware active (fw >= 0x02xx)\n"
                        "Run without --reset to continue.\n");
        else
            std::printf("Still in bootloader (fw=0x%02X%02X).\n",
                        v2.fw_hi, v2.fw_lo);
        radio.end();
        return 0;
    }

    lr1121::Radio radio;
    if (!radio.begin(cfg)) {
        std::fprintf(stderr, "ERROR: radio init failed\n"
                             "  Check: SPI enabled? wiring? DIO5/DIO6 connected?\n"
                             "  Run with -v for step-by-step output\n");
        return 1;
    }
    std::printf("Radio OK — listening (Ctrl+C to stop)\n\n");

    uint8_t buf[256];
    int     pkt = 0;
    for (;;) {
        lr1121::RxInfo info{};
        int r = radio.receive(buf, (uint8_t)(sizeof(buf) - 1), 30'000, &info);

        if (r > 0) {
            buf[r] = '\0';
            std::printf("[%4d] %d B  rssi=%d dBm  snr=%d dB  '%s'\n",
                        ++pkt, r, info.rssi_dbm, info.snr_db, buf);
        } else if (r == -1) {
            std::printf("       timeout (30s), still listening...\n");
        } else if (r == -2) {
            std::printf("       CRC error\n");
        }
    }

    radio.end();
    return 0;
}
