// batch_capture.cpp — pure logic for batch capture. See header.
// Unit-tested by tests/test_batch_capture.cpp.

#include "core/capture/batch_capture.h"

#include <algorithm>

namespace reasampler::capture {

std::vector<CaptureUnit> planCaptureUnits(const std::vector<BatchRange>& ranges) {
    std::vector<CaptureUnit> units;
    units.reserve(ranges.size());
    int ordinal = 0;
    for (const BatchRange& r : ranges) {
        // Drop empty/inverted ranges — the offline backend refuses end<=start too.
        if (!(r.endSeconds > r.startSeconds)) continue;
        ++ordinal;
        units.push_back({ordinal, r.startSeconds, r.endSeconds});
    }
    return units;
}

void BatchOutcome::record(int ordinal, bool ok, std::string detail) {
    results_.push_back({ordinal, ok, std::move(detail)});
}

std::size_t BatchOutcome::succeeded() const {
    return static_cast<std::size_t>(
        std::count_if(results_.begin(), results_.end(),
                      [](const BatchUnitResult& r) { return r.ok; }));
}

std::size_t BatchOutcome::failed() const {
    return results_.size() - succeeded();
}

std::vector<BatchUnitResult> BatchOutcome::failures() const {
    std::vector<BatchUnitResult> out;
    for (const BatchUnitResult& r : results_)
        if (!r.ok) out.push_back(r);
    return out;
}

std::string BatchOutcome::summaryLine(const std::string& noun) const {
    const std::size_t n  = total();
    const std::size_t ok = succeeded();

    if (n == 0)
        return "ReaSampler batch capture: nothing to capture.";

    const std::string plural = (n == 1) ? noun : noun + "s";

    if (ok == n)
        return "ReaSampler batch capture: " + std::to_string(ok) + " " +
               plural + " captured.";

    // Mixed / all-failed: report the ratio and enumerate the failed ordinals so the
    // user knows exactly which units to retry. No partial corruption is implied —
    // each captured unit is a complete, independent bank sample.
    std::string line = "ReaSampler batch capture: " + std::to_string(ok) + " of " +
                       std::to_string(n) + " " + plural + " captured (" +
                       std::to_string(n - ok) + " failed: ";
    bool first = true;
    for (const BatchUnitResult& f : results_) {
        if (f.ok) continue;
        if (!first) line += ", ";
        line += "#" + std::to_string(f.ordinal);
        first = false;
    }
    line += ").";
    return line;
}

} // namespace reasampler::capture
