#include "websocket_text_receiver.h"
#include <cassert>
#include <string>

int main() {
    char storage[16385];
    WebSocketTextReceiver receiver;
    receiver.set_storage(storage, sizeof(storage) - 1);
    using Result = WebSocketTextReceiver::Result;
    // Reproduce the 9502-byte speech_chunk transport splits observed on hardware.
    const std::string audio(9502, 'a');
    assert(receiver.receive(1, true, audio.data(), 1294, 9502, 0) == Result::INCOMPLETE);
    assert(receiver.receive(1, true, audio.data()+1294, 7788, 9502, 1294) == Result::INCOMPLETE);
    assert(receiver.receive(1, true, audio.data()+9082, 420, 9502, 9082) == Result::COMPLETE);
    assert(receiver.size() == audio.size() && std::string(receiver.data()) == audio);
    // A subsequent ordinary JSON message cannot reuse the previous audio tail.
    assert(receiver.receive(1, true, "{}", 2, 2, 0) == Result::COMPLETE);
    assert(receiver.size() == 2 && std::string(receiver.data()) == "{}");
    // Continuation frames and interleaved SDK control frames preserve text order.
    assert(receiver.receive(1, false, "{", 1, 1, 0) == Result::INCOMPLETE);
    assert(receiver.receive(9, true, "ping", 4, 4, 0) == Result::IGNORED);
    assert(receiver.receive(0, true, "}", 1, 1, 0) == Result::COMPLETE);
    assert(std::string(receiver.data()) == "{}");
    // Never parse a partial, discontinuous, oversized, or stale message.
    assert(receiver.receive(1, true, audio.data(), 10, 9502, 0) == Result::INCOMPLETE);
    assert(receiver.receive(1, true, audio.data()+11, 10, 9502, 11) == Result::REJECTED);
    assert(receiver.receive(0, true, "}", 1, 1, 0) == Result::REJECTED);
    assert(receiver.receive(1, true, audio.data(), 1, 16385, 0) == Result::REJECTED);
    assert(receiver.receive(1, false, audio.data(), 9502, 9502, 0) == Result::INCOMPLETE);
    assert(receiver.receive(0, true, audio.data(), 1, 9502, 0) == Result::REJECTED);
    assert(receiver.receive(1, true, "{", 1, 2, 0) == Result::INCOMPLETE);
    receiver.reset(); // Reconnection/error invalidates any unfinished text.
    assert(receiver.receive(1, true, "}", 1, 2, 1) == Result::REJECTED);
    assert(receiver.receive(1, true, nullptr, -1, 2, 0) == Result::REJECTED);
    assert(receiver.receive(1, true, "{}", 2, 2, 0) == Result::COMPLETE);
}
