#!/usr/bin/env python3
"""Compile production send_hello and verify the actual negotiated wire contract."""
import os
from pathlib import Path
import re
import subprocess
import tempfile

repo = Path(__file__).resolve().parents[2]
source = (repo / "firmware/main/cloud_client.cpp").read_text()
hello = re.search(r"^static void send_hello\(void\)\s*\{.*?^}", source, re.M | re.S).group()
cjson = Path(os.environ.get("CJSON_DIR", repo / ".cache/esp-idf-v5.5.4/components/json/cJSON"))
harness = r'''#include "cJSON.h"
#include <cassert>
#include <cstring>
#include <cstdio>
#define CONFIG_DEVICE_LAB_DEVICE_TOKEN "test-only-token"
#define DEVICE_LAB_FIRMWARE_VERSION "test-version"
#define ESP_LOGI(...) ((void)0)
static const char* s_device_id = "test-device";
static const char* TAG = "test";
static const char* board_slug() { return "m5stack-stopwatch"; }
static cJSON* captured = nullptr;
static bool send_json(cJSON* root) { captured = root; return true; }
'''
harness += hello
harness += r'''
int main() {
    (void)TAG;
    send_hello();
    assert(captured);
    assert(std::strcmp(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(captured, "type")), "hello") == 0);
    auto* capabilities = cJSON_GetObjectItemCaseSensitive(captured, "capabilities");
    assert(cJSON_IsArray(capabilities));
    // These capabilities unlock implemented read-only History and its button entry.
    const char* required[] = {"history", "catalog", "target-select", "native-interaction", "speech-settings"};
    for (auto* expected : required) {
        int matches = 0;
        cJSON* item = nullptr;
        cJSON_ArrayForEach(item, capabilities) {
            assert(cJSON_IsString(item));
            if (std::strcmp(item->valuestring, expected) == 0) ++matches;
            assert(std::strcmp(item->valuestring, "speech_playback") != 0);
        }
        assert(matches == 1);
    }
    cJSON_Delete(captured);
    std::puts("production hello advertises History and preserves playback freeze PASS");
}
'''
with tempfile.TemporaryDirectory(prefix="cloud-hello-") as folder:
    temp = Path(folder)
    (temp / "hello.cpp").write_text(harness)
    subprocess.run(["cc", "-c", str(cjson / "cJSON.c"), "-I", str(cjson), "-o", str(temp / "cjson.o")], check=True)
    subprocess.run(["c++", "-std=c++17", "-Wall", "-Wextra", "-Werror", "-I", str(cjson), str(temp / "hello.cpp"), str(temp / "cjson.o"), "-o", str(temp / "test")], check=True)
    subprocess.run([str(temp / "test")], check=True)
