#pragma once

#include <atomic>
#include <cstdint>

#include "radar_driver.hpp"
#include "run_config.hpp"
#include "shm_ring.hpp"
#include "switch_driver.hpp"

namespace radar::acq {

/**
 * @brief Produces raw sweep collections for configured switch combinations.
 *
 * Lifecycle:
 * 1. Open radar and switch drivers.
 * 2. Iterate configured combinations, acquire one sweep per combination.
 * 3. Publish serialized collections into the raw shared-memory ring.
 */
class SweepOrchestrator {
  public:
    /**
     * @param config Runtime config loaded from JSON.
     * @param radar_driver Radar device implementation.
     * @param input_switch_driver Switch connected to radar input path.
     * @param output_switch_driver Switch connected to radar output path.
     * @param raw_ring Shared-memory ring for raw collections.
     * @param raw_tap_ring Optional tap ring for GUI/debug readers.
     */
    SweepOrchestrator(
        const config::RunConfig& config,
        drivers::RadarDriver& radar_driver,
        drivers::SwitchDriver& input_switch_driver,
        drivers::SwitchDriver& output_switch_driver,
        ipc::ShmRing& raw_ring,
        ipc::ShmRing* raw_tap_ring = nullptr
    );

    /**
     * @brief Run acquisition loop until stop is requested or single run completes.
     */
    void run(const std::atomic<bool>& stop_requested);

  private:
    /**
     * @brief Acquire one collection for all configured combinations.
     */
    [[nodiscard]] auto acquire_one_collection(std::uint64_t collection_id, const std::atomic<bool>& stop_requested)
        -> ipc::RawSweepCollection;

    const config::RunConfig& config_;
    drivers::RadarDriver& radar_driver_;
    drivers::SwitchDriver& input_switch_driver_;
    drivers::SwitchDriver& output_switch_driver_;
    ipc::ShmRing& raw_ring_;
    ipc::ShmRing* raw_tap_ring_ = nullptr;
};

}  // namespace radar::acq
