BareGit
#pragma once

#include <atomic>
#include <cstddef>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <sys/types.h>

#include "protocol.hpp"

namespace nethack_mcp
{

/// Spawn and supervise one isolated NetHack worker process.
class EngineProcess
{
public:
    /// Receive worker events from the reader thread.
    using EventCallback = std::function<void(const Json&)>;

    /// Construct an idle process supervisor.
    EngineProcess() = default;

    /// Stop a worker and reap it before destroying the supervisor.
    ~EngineProcess();

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

    /// Spawn a worker and send its validated start message.
    bool start(const Json& start_message, EventCallback callback,
               std::string& error,
               std::size_t max_diagnostic_bytes = 1024U * 1024U);

    /// Send one validated input message to the worker.
    bool send(const Json& message, std::string& error);

    /// Request termination and wait for the child and reader threads.
    void terminate(bool force = false);

    /// Report whether the child has not yet been reaped.
    bool running() const;

private:
    void readLoop();
    void diagnosticLoop(int descriptor);
    std::string executablePath() const;

    pid_t process_id_ = -1;
    std::unique_ptr<FramedChannel> channel_;
    EventCallback callback_;
    std::thread reader_thread_;
    std::thread diagnostic_thread_;
    std::size_t max_diagnostic_bytes_ = 1024U * 1024U;
    mutable std::mutex state_mutex_;
    std::atomic<bool> running_ = false;
};

} // namespace nethack_mcp