#!/usr/bin/env bash
# 真实网关冒烟（扩展版）：覆盖 kilo 问答 + Context7 远程 MCP + filesystem stdio MCP + 代理转发。
#
# 与 MockServer 集成测试互补——这是真实 wire（非模拟），覆盖 M10/M13 验收项。
#
# 前置：
#   - ~/.pi/agent/auth.json 里有 kilo 的 key（从 pi 配置读取，不硬编码）
#   - 已构建 release 二进制（cargo build --release）
#   - 可选：npx（用于 filesystem MCP）、代理进程（1080 socks / 1081 http）
#
# 环境变量覆盖：
#   SMOKE_KILO_KEY  —— kilo API key（默认从 ~/.pi/agent/auth.json 读）
#   SMOKE_MODEL     —— 模型（默认 tencent/hy3:free）

set -uo pipefail
cd "$(dirname "$0")/.."   # 项目根

MODEL="${SMOKE_MODEL:-tencent/hy3:free}"
BIN=target/release/hey
[ -x "$BIN" ] || { echo "error: $BIN missing — run cargo build --release first" >&2; exit 1; }

# 从 pi auth.json 读 key（或环境变量覆盖）
KILO_KEY="${SMOKE_KILO_KEY:-}"
if [ -z "$KILO_KEY" ]; then
  KILO_KEY="$(python3 -c "
import json, sys
try:
    print(json.load(open('$HOME/.pi/agent/auth.json'))['kilo']['key'])
except Exception as e:
    sys.exit(0)  # 没 key 跳过 kilo 测试
")" || true
fi

# 临时 config + 会话目录，退出即清理
CFG="$(mktemp /tmp/hey_smoke_XXXX.toml)" && chmod 600 "$CFG"
SSDIR="$(mktemp -d /tmp/hey_smoke_sess_XXXX)"
trap 'rm -f "$CFG"; rm -rf "$SSDIR"' EXIT

# 生成配置（含 kilo provider + MCP 段）
export KILO_KEY MODEL CFG
python3 - <<'PY' || true
import os, json
cfg_path = os.environ['CFG']
key = os.environ.get('KILO_KEY', '')
model = os.environ['MODEL']

lines = []
# 基础 provider
lines.append(f'[provider.kilo]')
lines.append(f'protocol = "openai"')
lines.append(f'base_url = "https://api.kilo.ai/api/openrouter"')
lines.append(f'api_key = "{key}"')
lines.append(f'models = ["{model}"]')
lines.append(f'effort = "low"')
lines.append(f'context_window = 262144')
lines.append('')

# 代理（如果端口在监听）
proxy_http = False
proxy_socks = False
try:
    import socket
    s = socket.socket()
    s.settimeout(0.5)
    s.connect(('127.0.0.1', 1081))
    s.close()
    proxy_http = True
except: pass
try:
    s = socket.socket()
    s.settimeout(0.5)
    s.connect(('127.0.0.1', 1080))
    s.close()
    proxy_socks = True
except: pass

if proxy_socks:
    lines.append('[proxy]')
    lines.append('url = "socks5://127.0.0.1:1080"')
    lines.append('connect_timeout_secs = 10')
    lines.append('')
elif proxy_http:
    lines.append('[proxy]')
    lines.append('url = "http://127.0.0.1:1081"')
    lines.append('connect_timeout_secs = 10')
    lines.append('')

# Context7 远程 MCP（始终添加，检测可用性在测试时）
lines.append('[mcp.context7]')
lines.append('url = "https://mcp.context7.com/mcp"')
lines.append('respawn = false')
lines.append('')

# filesystem MCP（npx）
lines.append('[mcp.filesystem]')
lines.append('command = "npx"')
lines.append('args = ["-y", "@modelcontextprotocol/server-filesystem", "/home/yanggz/code/hey"]')
lines.append('')

# 权限全开
lines.append('[permission]')
lines.append('')

with open(cfg_path, 'w') as f:
    f.write('\n'.join(lines))

# 输出检测摘要供脚本判断
print(f'proxy: socks={proxy_socks} http={proxy_http}', flush=True)
PY

# 检测 MCP 可用性
context7_ok=false
timeout 5 curl -s -o /dev/null -w '%{http_code}' https://mcp.context7.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}' \
  2>/dev/null | grep -q 200 && context7_ok=true

npx_ok=false
command -v npx &>/dev/null && npx_ok=true

PASS=0; FAIL=0; SKIP=0

run() {  # run <label> <prompt> <expect> [timeout_secs]
    local label="$1" prompt="$2" expect="$3" timeout="${4:-120}" out
    out="$(timeout "$timeout" "$BIN" --config "$CFG" --sessions-dir "$SSDIR" -m "kilo/$MODEL" -p "$prompt" 2>&1)"
    if grep -qF "$expect" <<<"$out"; then
        echo "  pass $label"; PASS=$((PASS+1))
    else
        echo "  FAIL $label (expected: $expect, timeout: ${timeout}s)"
        echo "$out" | tail -10
        FAIL=$((FAIL+1))
    fi
}

echo "===== hey 真实面冒烟测试 ====="
echo "model=$MODEL  config=$CFG"
echo ""

# ----- 1. kilo 基础问答 -----
echo "--- 1. kilo 基础问答 ---"
if [ -n "$KILO_KEY" ]; then
    run "text" "Reply with exactly: kilo OK" "kilo OK"
else
    echo "  skip text (no KILO_KEY)"; SKIP=$((SKIP+1))
fi

# ----- 2. Context7 远程 MCP -----
echo "--- 2. Context7 远程 MCP ---"
if $context7_ok && [ -n "$KILO_KEY" ]; then
    run "tools_listed" \
      "列出所有可用工具名（只列名字，一行一个，不要解释）" \
      "context7_resolve-library-id" 150
else
    echo "  skip context7 (unreachable=$context7_ok key=$([ -n "$KILO_KEY" ] && echo set || echo unset))"; SKIP=$((SKIP+1))
fi

# ----- 3. filesystem MCP -----
echo "--- 3. filesystem MCP ---"
if $npx_ok && [ -n "$KILO_KEY" ]; then
    # 测试文件必须建在 server 允许目录内（server args 里写的 /home/yanggz/code/hey），
    # 放 /tmp 会被 server 拒绝（Access denied）——那不是 hey 的回归。
    ALLOWED="${SMOKE_FS_ROOT:-/home/yanggz/code/hey}"
    TMPF="$ALLOWED/.smoke_fs_test_$$.txt"
    echo "smoke-e2e-ok" > "$TMPF"
    run "filesystem_read" \
      "Use filesystem_read_text_file to read $TMPF and report its content." \
      "smoke-e2e-ok" 150
    rm -f "$TMPF"
else
    echo "  skip filesystem (npx=$npx_ok key=$([ -n "$KILO_KEY" ] && echo set || echo unset))"; SKIP=$((SKIP+1))
fi

# ----- 4. 代理转发 -----
echo "--- 4. 代理转发 ---"
if [ -n "$KILO_KEY" ]; then
    # 不管代理是否配置，都尝试用 socks5 代理发一次请求
    # 用临时环境变量覆盖代理
    if ss -tlnp 2>/dev/null | grep -qE '108[01]'; then
        # 用显式代理配置跑一次
        PROXY_CFG="$(mktemp /tmp/hey_smoke_proxy_XXXX.toml)" && chmod 600 "$PROXY_CFG"
        python3 -c "
import os
with open(os.environ['PROXY_CFG'], 'w') as f:
    f.write('''[provider.kilo]
protocol = \"openai\"
base_url = \"https://api.kilo.ai/api/openrouter\"
api_key = \"${KILO_KEY}\"
models = [\"${MODEL}\"]
effort = \"low\"

[proxy]
url = \"socks5://127.0.0.1:1080\"
connect_timeout_secs = 10
read_timeout_secs = 0
''')
" 2>/dev/null
        out="$(timeout 120 "$BIN" --config "$PROXY_CFG" --sessions-dir "$SSDIR" -m "kilo/$MODEL" -p "Reply with exactly: proxy OK" 2>&1)"
        rm -f "$PROXY_CFG"
        if grep -qF "proxy OK" <<<"$out"; then
            echo "  pass proxy"; PASS=$((PASS+1))
        else
            echo "  FAIL proxy — output:"; echo "$out" | head -5; FAIL=$((FAIL+1))
        fi
    else
        echo "  skip proxy (no proxy listening on 1080/1081)"; SKIP=$((SKIP+1))
    fi
else
    echo "  skip proxy (no KILO_KEY)"; SKIP=$((SKIP+1))
fi

echo "----"
echo "pass=$PASS fail=$FAIL skip=$SKIP"
[ "$FAIL" -eq 0 ] && exit 0 || exit 1
