/*
 * test_envelope — round-trip an Envelope through FrameCodec + encode/decode.
 * Runs only under dev (requires protobuf).
 */
#include <cstdio>
#include <cstring>
#include <vector>

#include "protocol/envelope.h"
#include "protocol/protocol.h"

using namespace voicecat::protocol;

static int g_failures = 0;

#define CHECK(cond)                                                        \
    do {                                                                   \
        if (!(cond)) {                                                     \
            std::printf("FAIL [%s:%d]: %s\n", __FILE__, __LINE__, #cond); \
            ++g_failures;                                                  \
        }                                                                  \
    } while (0)

int main() {
    // Build a ClientHello envelope.
    voicecat::v1::Envelope out_env;
    out_env.set_request_id(42);
    auto* hello = out_env.mutable_client_hello();
    hello->set_proto_version(1);
    hello->set_client_name("test-client");
    hello->set_client_version("0.0.1");
    hello->add_features("text");

    // encode_envelope → framed wire bytes
    std::vector<uint8_t> wire;
    bool enc_ok = encode_envelope(out_env, wire);
    CHECK(enc_ok);
    CHECK(wire.size() > kLengthHeaderSize);

    // Feed through FrameCodec to extract the payload
    FrameCodec codec;
    std::vector<std::vector<uint8_t>> frames;
    bool feed_ok = codec.feed(wire.data(), wire.size(), frames);
    CHECK(feed_ok);
    CHECK(frames.size() == 1);

    // decode_envelope from the extracted payload
    voicecat::v1::Envelope in_env;
    bool dec_ok = decode_envelope(frames[0], in_env);
    CHECK(dec_ok);

    // Verify round-trip fidelity
    CHECK(in_env.request_id() == 42);
    CHECK(in_env.has_client_hello());
    CHECK(in_env.client_hello().proto_version() == 1);
    CHECK(std::strcmp(in_env.client_hello().client_name().c_str(), "test-client") == 0);
    CHECK(in_env.client_hello().features_size() == 1);
    CHECK(std::strcmp(in_env.client_hello().features(0).c_str(), "text") == 0);

    // next_request_id() is monotonically increasing
    uint64_t r1 = next_request_id();
    uint64_t r2 = next_request_id();
    CHECK(r2 == r1 + 1);

    // Empty envelope round-trips cleanly
    {
        voicecat::v1::Envelope empty;
        std::vector<uint8_t> w2;
        CHECK(encode_envelope(empty, w2));
        FrameCodec c2;
        std::vector<std::vector<uint8_t>> f2;
        CHECK(c2.feed(w2.data(), w2.size(), f2));
        CHECK(f2.size() == 1);
        voicecat::v1::Envelope e2;
        CHECK(decode_envelope(f2[0], e2));
        CHECK(e2.request_id() == 0);
        CHECK(e2.body_case() == voicecat::v1::Envelope::BODY_NOT_SET);
    }

    if (g_failures == 0) {
        std::printf("envelope: all checks passed\n");
        return 0;
    }
    std::printf("envelope: %d failure(s)\n", g_failures);
    return 1;
}
