#pragma once
#include <algorithm>
#include <cstring>

constexpr size_t AGENT_FINAL_MAX_BYTES = 2048;

inline size_t agent_text_prefix_bytes(const char *value,size_t capacity) {
    size_t size=std::min(std::strlen(value),capacity-1);
    while (size && (static_cast<unsigned char>(value[size]) & 0xc0U)==0x80U) --size;
    return size;
}

template<size_t N> void copy_agent_final(char (&out)[N], const char *value) {
    value=value?value:"";
    const size_t size=agent_text_prefix_bytes(value,N);
    std::memcpy(out,value,size);
    out[size]='\0';
}

// Compare exactly the UTF-8 prefix that copy_agent_final can store. Comparing
// N-1 raw bytes falsely changes a name when its last glyph crosses the boundary.
template<size_t N> bool stored_agent_text_equal(const char (&stored)[N],const char *value) {
    value=value?value:"";
    const size_t size=agent_text_prefix_bytes(value,N);
    return std::strlen(stored)==size && std::memcmp(stored,value,size)==0;
}

struct AgentDisplayText { const char *text; bool terminal; bool tool; };

inline AgentDisplayText agent_display_text(const char *state, const char *final_text,
        const char *activity_type, const char *latest_activity, const char *recent_text) {
    const bool terminal=state && (std::strcmp(state,"DONE")==0 || std::strcmp(state,"FAILED")==0);
    // nullptr means an older Gateway: preserve its activity display for Pi/Codex.
    // An explicit empty terminal reply must not present tool logs as the answer.
    if (terminal && final_text)
        return {*final_text?final_text:"No final response received.",true,false};
    const bool persisted=state && (std::strcmp(state,"DORMANT")==0 || std::strcmp(state,"IDLE")==0);
    if (persisted && final_text && *final_text)
        return {final_text,true,false};
    const bool tool=activity_type && std::strcmp(activity_type,"tool")==0;
    return {tool?latest_activity:recent_text,false,tool};
}
