// firmware/fieldtest_beacon/src/main.cpp
// 20260212 ChatGPT
// $Id$
// $HeadURL$

#include <Arduino.h>
#include <SPI.h>
#include <SD.h>
#include "Boards.h"

// Include microReticulum headers from your external tree
#include "Identity.h"
#include "Reticulum.h"
#include "Destination.h"
#include "Transport.h"

// ---------- User-tunable ----------
static const uint32_t BEACON_INTERVAL_MS = 15000;
static const char* PATH_IDENTITY_BIN = "/provisioning/identity.bin";
static const char* PATH_LABEL_TXT    = "/provisioning/label.txt";
static const char* LOG_PATH          = "/logs/fieldtest.log";

// ---------- Globals ----------
static uint32_t g_iter = 0;
static uint32_t g_next_tx = 0;
static File g_log;

// Source board pin mapping from microReticulum_Firmware board definitions.
static const int SD_CS_PIN = SD_CS;

// Simple line logger (append-only)
static void log_line(const String& line) {
  if (!g_log) return;
  g_log.println(line);
  g_log.flush();
}

// Read whole file into a buffer
static bool read_file(const char* path, std::vector<uint8_t>& out) {
  File f = SD.open(path, FILE_READ);
  if (!f) return false;
  size_t n = f.size();
  out.resize(n);
  if (n > 0) f.read(out.data(), n);
  f.close();
  return true;
}

static String read_text_file(const char* path) {
  File f = SD.open(path, FILE_READ);
  if (!f) return String("");
  String s = f.readString();
  f.close();
  s.trim();
  return s;
}

void setup() {
  Serial.begin(115200);
  delay(250);

  // ---- SD init ----
  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("SD init failed");
    return;
  }

  g_log = SD.open(LOG_PATH, FILE_APPEND);
  if (!g_log) {
    Serial.println("Failed to open log file");
    return;
  }

  const String label = read_text_file(PATH_LABEL_TXT);
  log_line("BOOT\tlabel=" + label);

  std::vector<uint8_t> id_bytes;
  if (!read_file(PATH_IDENTITY_BIN, id_bytes)) {
    log_line(String("ERROR\tmissing_identity\tpath=") + PATH_IDENTITY_BIN);
    return;
  }
  log_line(String("IDENTITY_OK\tbytes=") + id_bytes.size());

  // ---- Load Identity into microReticulum ----
  // TODO: adjust to the actual API in your microReticulum version
  // Example intent:
  //   Identity ident = Identity::fromBytes(id_bytes.data(), id_bytes.size());
  //   Reticulum rns;
  //   rns.setIdentity(ident);
  //   rns.begin(...);
  //
  // Also: initialize your LoRa Interface and attach it to Reticulum here.

  log_line("RNS_INIT_OK");

  g_next_tx = millis() + 3000; // wait a moment before first TX
}

void loop() {
  // TODO: run microReticulum polling / tick function, and radio interface polling

  const uint32_t now = millis();
  if ((int32_t)(now - g_next_tx) >= 0) {
    g_next_tx = now + BEACON_INTERVAL_MS;

    // Build payload: timestamp + iterator (GPS later)
    const uint32_t epoch_guess = (uint32_t) (time(nullptr)); // placeholder; GPS later
    const String payload = String("t=") + epoch_guess + " i=" + g_iter++;

    // TODO: send to peer(s) (Destination derived from peers list)
    // bool ok = destination.send(payload_bytes, len);

    log_line(String("TX\t") + payload);
  }

  delay(5);
}
