#pragma once

#include <atomic>
#include <cstdint>
#include <vector>

#include "calibration_master.hpp"
#include "reference_master.hpp"
#include "run_config.hpp"
#include "shm_ring.hpp"

namespace radar::preprocessing {

class DataPreprocessor {
  public:
    DataPreprocessor(
        const config::RunConfig& config,
        CalibrationMaster& calibration_master,
        ReferenceMaster& reference_master,
        ipc::ShmRing& raw_ring,
        ipc::ShmRing& preprocessed_ring,
        ipc::ShmRing* preprocessed_tap_ring = nullptr
    );

    // Main processing loop. Runs until stop flag is set.
    void run(const std::atomic<bool>& stop_requested);

  private:
    void validate_startup_prerequisites() const;
    [[nodiscard]] auto try_pop_raw_collection(
        std::vector<std::uint8_t>& serialized_raw,
        ipc::RawSweepCollection* out_collection
    ) -> bool;
    void publish_preprocessed_collection(const ipc::PreprocessedCollection& collection);

    [[nodiscard]] auto preprocess_collection(const ipc::RawSweepCollection& raw_collection) const
        -> ipc::PreprocessedCollection;

    const config::RunConfig& config_;
    CalibrationMaster& calibration_master_;
    ReferenceMaster& reference_master_;
    ipc::ShmRing& raw_ring_;
    ipc::ShmRing& preprocessed_ring_;
    ipc::ShmRing* preprocessed_tap_ring_ = nullptr;
};

}  // namespace radar::preprocessing
