#pragma once

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "calibrator_interface.hpp"
#include "shared_types.hpp"

namespace radar::preprocessing {

class CalibrationMaster {
  public:
    // `calibrator` encapsulates the actual calibration algorithm (v1: through).
    explicit CalibrationMaster(std::unique_ptr<CalibratorInterface> calibrator);

    // Loads a serialized raw sweep bundle with one calibration standard per combo.
    void load_bundle(const std::string& path);
    // Ensures all runtime combos are present in loaded standards.
    void validate_combos(const std::vector<ipc::ComboKey>& combos) const;
    // Applies calibration standard corresponding to measured trace combo.
    [[nodiscard]] auto apply(const ipc::SweepTraceBlock& measured_trace) const -> ipc::SweepTraceBlock;

  private:
    std::unique_ptr<CalibratorInterface> calibrator_impl_;
    std::unordered_map<ipc::ComboKey, ipc::SweepTraceBlock, ipc::ComboKeyHash> standards_by_combo_{};
};

[[nodiscard]] auto make_through_calibrator() -> std::unique_ptr<CalibratorInterface>;

}  // namespace radar::preprocessing
