#pragma once

#include <cstdint>
#include <fstream>
#include <string>

#include "Tick.h"

struct Command;

// 64-bit hash (16-char hex) over the *.toml files in configDir. Stored in the
// replay header and recomputed on playback to detect a config mismatch.
std::string computeReplayConfigHash(const std::string& configDir);

// Writes a replay file as the game runs (see docs/replay_design.md). The format
// is line-oriented append-friendly text: a small keyed header, then one line per
// command (tick-tagged) interleaved with RNG-state checksum lines for desync
// detection. Each line is flushed so a crash mid-run still leaves a valid partial
// file.
//
// One file = one run between Reset boundaries; startNewRun() closes the current
// file and opens a fresh one.
class ReplayRecorder
{
public:
    // configDir: hashed (its *.toml files) into the header for config-mismatch
    //   detection on playback. outputDir: where .replay files are written.
    ReplayRecorder(std::string configDir, std::string outputDir);
    ~ReplayRecorder();

    ReplayRecorder(const ReplayRecorder&) = delete;
    ReplayRecorder& operator=(const ReplayRecorder&) = delete;

    // Close any current file, then open a fresh one (named <timestamp>_<seed>),
    // write the header, and record an initial tick-0 checksum. A run boundary.
    void startNewRun(unsigned int seed, std::uint64_t initialRngFingerprint);

    // Append one command line tagged with the tick it was applied at, followed by
    // the post-apply RNG checksum.
    void recordCommand(Tick tick, const Command& command, std::uint64_t rngFingerprint);

    // Append a periodic RNG checksum line.
    void recordChecksum(Tick tick, std::uint64_t rngFingerprint);

    void close();
    bool isOpen() const;
    const std::string& getCurrentFilePath() const;

private:
    std::string   m_configDir;
    std::string   m_outputDir;
    std::string   m_filePath;
    std::ofstream m_stream;
};
