#pragma once
// bake_landing — landing ONE bake request into the loaded project's bank: read the staged
// WAV, collapse it losslessly to mono when it is dual-mono, hash it, resolve replace-vs-add,
// write the file, index it, seed its lineage. The scan pass that finds requests across the
// open tabs and answers them is `bake_land`; this is what it calls per request, and it
// neither reads nor writes an ext-state key.

#include <cstdint>
#include <string>

#include "core/wire/bake_wire.h"

namespace reasampler {
class ReaSamplerSession;
}

namespace reasampler::capture {

// A refusal outcome shaped for the key it will be written back to. Shared with the scan
// pass, which refuses on grounds no single landing can see — a request from another tab, or
// a landing the pass then failed to persist.
wire::BakeOutcome refuseBake(wire::BakeStatus status, std::string message,
                             std::int64_t generation);

// One request landed, with the two failure truths kept apart: a throw out of the prepare
// half is a refusal that left the project untouched, while a throw out of the commit half
// may have written a file and changed the book — calling that one "refused" would tell the
// user nothing happened when something did.
struct LandingAttempt {
    wire::BakeOutcome outcome;
    bool partial = false;      // the commit threw: a file and/or an entry may exist
    bool changedBook = false;  // the book gained or refreshed an entry, unpersisted so far
};

// Never throws: both halves run under their own catch, and which half threw is what
// `partial` carries. Mutates book + ledger WITHOUT persisting — the caller persists once
// for its whole batch, which is why no landing may report itself as banked.
LandingAttempt attemptLanding(ReaSamplerSession& session, const std::string& projectDir,
                              const wire::BakeRequest& request);

}  // namespace reasampler::capture
