#pragma once
// capture_name — the REAPER-free composition of one capture's label and file-stem base
// from its source-track name(s), a local-calendar discriminator, and an optional batch
// ordinal. The shell reads the names and the clock; the SHAPE of a capture's name is
// decided here so it is testable without a DAW.

#include <cstddef>
#include <string>
#include <vector>

namespace reasampler::capture {

// The capture's own moment, already broken down into LOCAL calendar fields by the shell.
// Passing fields rather than an epoch is what keeps the format deterministic under test:
// an epoch would render differently per machine timezone. month < 1 or day < 1 means
// "no stamp" and suppresses the discriminator entirely.
struct CaptureStamp {
    int month  = 0;   // 1-12
    int day    = 0;   // 1-31
    int hour   = 0;   // 0-23
    int minute = 0;   // 0-59
};

// Longest source-name prefix kept in either the label or the stem. Real track names sit
// far under it; the bound exists so a pathological name cannot push the rendered file
// path toward the platform's limit, and so a label and its file still read as the same
// name.
inline constexpr std::size_t kMaxSourceNameBytes = 64;

struct CaptureNameInputs {
    // Source-track names in source order — the first non-empty one names the capture,
    // the rest only contribute the "+N" multi-source marker.
    std::vector<std::string> sourceNames;

    CaptureStamp stamp;

    // Batch unit ordinal; <= 0 for a single capture.
    int ordinal = 0;

    // The scope literal ("item"/"track"/"realtime"), used ONLY when no source name
    // resolved at all — otherwise the source name wins.
    std::string fallback = "capture";
};

struct CaptureName {
    // Sample::displayName. Legible, carries the source name verbatim, and is explicitly
    // NOT unique (core/model/CLAUDE.md §resample_name) — the stamp serves the eye.
    std::string label;

    // deriveBankPaths' baseName. Still passes through sanitizeStem, and stem uniqueness
    // is still entirely makeUniqueTag's job.
    std::string stemBase;
};

// "MM-DD HHMM" (e.g. "08-01 1432"); empty when the stamp carries no calendar date.
// Year is deliberately omitted: the card and the browse list are narrow, and Sample
// carries the full createdTimestamp for anything needing the exact moment.
std::string formatCaptureStamp(const CaptureStamp& stamp);

CaptureName composeCaptureName(const CaptureNameInputs& in);

// The single source of truth for the word itself — kCaptureTrackPrefixBare and
// kCaptureTrackPrefix below both expand from this one token, so editing it can never
// desync captureTrackName's "no readable source name" bare-word fallback from the
// separator-terminated prefix it is derived from.
#define REASAMPLER_CAPTURE_TRACK_WORD "Capture"

// The bare word behind kCaptureTrackPrefix, needed by captureTrackName's
// no-readable-source-name fallback.
inline constexpr const char* kCaptureTrackPrefixBare = REASAMPLER_CAPTURE_TRACK_WORD;

// Prefixed onto a source track's name to name the track a render-in-place created.
// A display convention, not a persisted key — unlike a lane prefix or an action-id
// suffix, changing it later strands nothing.
inline constexpr const char* kCaptureTrackPrefix = REASAMPLER_CAPTURE_TRACK_WORD " ";

// The new track's name for a render of `sourceName`. IDEMPOTENT — a fixed point on
// its own output, so a second render over a result track yields "Capture MONEY"
// again rather than "Capture Capture MONEY". A counter suffix is deliberately not
// offered: REAPER does not uniquify track names either, and what distinguishes two
// renders of one source is their position, not their name.
std::string captureTrackName(const std::string& sourceName);

} // namespace reasampler::capture
