#pragma once
// Scope/source resolution shared by every capture entry point. Three concerns:
//   * range inference — razor union else time selection, orthogonal to scope;
//   * source-track collection — selected tracks (Track scope) or selected items'
//     owning tracks (Item scope), deduped, with canonical GUIDs;
//   * provenance-assembly inputs — resample-from-sample detection + the thin
//     capture-recipe fingerprint built from the live (un-bypassed) chain.
//
// All reads are non-destructive: selection, razor, and time selection are read,
// never mutated. The .cpp includes reaper_plugin_functions.h WITHOUT
// REAPERAPI_IMPLEMENT (main.cpp owns the API pointers). MediaTrack is forward-
// declared (via capture.h) so this header stays SDK-lite.

#include <optional>
#include <string>
#include <vector>

#include "shell/capture/capture.h"          // CaptureRequest, MediaTrack fwd
#include "core/capture/render_settings.h"   // CaptureScope
#include "core/model/provenance.h"          // model::Provenance

namespace reasampler {
class BankBook;
}

namespace reasampler::capture {

// The resolved source: exact bounds + the source tracks (for FX-bypass + Sample
// provenance GUIDs). `sourceTracks` holds the item-owning tracks (Item scope) or the
// selected tracks (Track scope).
struct ResolvedSource
{
    double                    startSeconds = 0.0;
    double                    endSeconds   = 0.0;
    std::vector<MediaTrack*>  sourceTracks;
    std::vector<std::string>  trackGuids;

    // Parallel to sourceTracks (one entry per track, in the same order) — the names the
    // capture is labeled and filed after. trackGuids is NOT parallel: an unreadable GUID
    // is dropped there, while an unreadable name still holds its track's slot.
    std::vector<std::string>  trackNames;

    // Item scope only: does the selected items' own extent already print
    // [startSeconds, endSeconds)? Feeds sourceModeForScope. Defaults false so a
    // hand-built source fails closed to the time-bounded render — a caller whose
    // range IS the item extent (batch item capture) says so explicitly.
    bool                      itemExtentIsWindow = false;
};

// Reads every track's P_RAZOREDITS and returns the union of parsed track-audio
// areas. Reads only — never clears the razor selection.
bool resolveRazorRange(double& start, double& end);

// Infers the render range for any scope: razor union when present, else the time
// selection. Returns false with a reason when neither yields a non-empty range.
bool resolveRange(double& start, double& end, std::string& why);

// Collects the selected tracks (Track scope) into out.sourceTracks + GUIDs + names.
bool collectSelectedTracks(ResolvedSource& out);

// The track's display name. GetTrackName (SDK header ~3626) is used rather than P_NAME
// because it already answers REAPER's own convention for an unnamed track ("Track N"),
// which is exactly the deterministic fallback a capture label wants; P_NAME would hand
// back an empty string instead. `[verify]` the SDK header states neither that the read is
// non-mutating nor what a `false` return means; the call site treats it as read-only and
// treats `false` (or a `true` with an untouched buffer) the same way — an empty name, which
// falls through to the scope literal fallback either way, so both readings are safe.
// Callers that build a ResolvedSource by hand (batch capture) use this directly.
std::string trackName(MediaTrack* tr);

// Resolves the source for a scope: the selection tracks (item/track), plus the
// inferred range. Returns false with a reason on nothing to do.
bool ResolveScopeSource(CaptureScope scope, ResolvedSource& out, std::string& why);

// Current project's directory (parent of its .rpp), forward-slashed, no trailing
// slash. Empty for an unsaved project (no false parentage). Read-only.
std::string currentProjectDir();

// Builds the provenance for a capture if it genuinely resamples from a bank sample
// (detectParent over `book`'s resolved file refs), else returns nullopt (the common,
// non-resample case). Must run BEFORE the FxBypassGuard neutralizes the in-scope
// chain — the source FX-chain identity is read from the live chain.
std::optional<model::Provenance> buildCaptureProvenance(
    const BankBook& book, const CaptureRequest& req,
    CaptureScope scope, const ResolvedSource& src);

}  // namespace reasampler::capture
