# yaml-language-server: $schema=./probe-config.schema.json

server:
  listen:
    host: "127.0.0.1"
    port: "${server_port|3000}"
  storage:
    dataDir: "/tmp/probes_data"
  # logging:
  #   level: "info"
  #   console:
  #     level: "info"
  #   file:
  #     level: "info"
  #     path: "/var/log/dial/dial.log"
  #     rotation:
  #       size: "50MB"
  #       frequency: "daily"
  #       maxFiles: 14

probes:
  execution:
    maxConcurrentChecks: "${max_checks|20}"

variables:
  env_name: "演示"
  httpbin_base: "https://httpbin.org"
  api_token: "Bearer demo-token"
  max_checks: 20
  server_port: 3000
  sqlite_url: "sqlite://:memory:"

targets:
  # ========== HTTP targets ==========

  - id: "baidu-home"
    name: "Baidu 首页可用"
    description: "监控百度首页的可用性和响应时间"
    type: http
    group: "搜索引擎"
    http:
      url: "https://www.baidu.com"
    expect:
      status: [200]
      durationMs:
        lte: 5000

  - id: "httpbin-json"
    name: "${env_name} JSON API — 完整流水线"
    type: http
    group: "后端服务"
    interval: "1m"
    timeout: "15s"
    http:
      url: "${httpbin_base}/json"
      headers:
        Accept: "application/json"
        Authorization: "${api_token|Bearer fallback-token}"
    expect:
      headers:
        Content-Type:
          contains: "application/json"
      durationMs:
        lte: 8000
      body:
        - json:
            path: "$.slideshow.title"
            equals: "Sample Slide Show"
        - json:
            path: "$.slideshow.slides[0].title"
            contains: "Wake"
        - regex: '"title"'

  - id: "httpbin-post"
    name: "POST 接口测试"
    type: http
    http:
      url: "${httpbin_base}/post"
      method: POST
      headers:
        Content-Type: "application/json"
      body: '{"action":"check","version":1}'
    expect:
      status: [200]
      body:
        - json:
            path: "$.json.action"
            equals: "check"
        - json:
            path: "$.json.version"
            gte: 1

  # ========== Cmd targets ==========

  - id: "bun-version"
    name: "Bun 版本输出匹配"
    type: cmd
    group: "系统检查"
    cmd:
      exec: "bun"
      args: ["--version"]
    expect:
      exitCode: [0]
      stdout:
        - regex: "^\\d+\\.\\d+\\.\\d+"

  - id: "bun-stdout-rules"
    name: "多规则 stdout 顺序校验"
    type: cmd
    interval: "5m"
    cmd:
      exec: "bun"
      args: ["-e", "console.log('version: 2.0.1, status: healthy')"]
    expect:
      stdout:
        - contains: "version:"
        - regex: "\\d+\\.\\d+\\.\\d+"
        - contains: "healthy"

  - id: "bun-stderr"
    name: "stderr 内容检查"
    type: cmd
    cmd:
      exec: "bun"
      args: ["-e", "process.stderr.write('simulated error\\n'); process.exit(1)"]
    expect:
      exitCode: [1]
      stderr:
        - contains: "simulated error"

  # ========== DB targets ==========

  - id: "sqlite-connect"
    name: "SQLite 内存数据库连接测试"
    type: db
    group: "数据库"
    db:
      url: "${sqlite_url}"
    expect:
      durationMs:
        lte: 1000

  - id: "sqlite-query"
    name: "SQLite 内存数据库多列结果校验"
    type: db
    db:
      url: "${sqlite_url}"
      query: "SELECT 1 as id, 'Alice' as name, 'engineer' as role"
    expect:
      rowCount: 1
      rows:
        - id:
            gte: 1
          name:
            exists: true
          role:
            contains: "engineer"
      result:
        - json:
            path: "$.rows[0].role"
            equals: "engineer"

  # ========== TCP targets ==========

  - id: "redis-port"
    name: "Redis 端口可达"
    type: tcp
    group: "基础设施"
    tcp:
      host: "127.0.0.1"
      port: 6379
    expect:
      durationMs:
        lte: 3000

  - id: "smtp-banner"
    name: "SMTP Banner 探测"
    type: tcp
    group: "基础设施"
    tcp:
      host: "127.0.0.1"
      port: 25
      readBanner: true
      bannerReadTimeout: 3000
    expect:
      banner:
        - contains: "ESMTP"

  # ========== ICMP targets ==========

  - id: "gateway-icmp"
    name: "网关 ICMP 可达"
    type: icmp
    group: "基础设施"
    icmp:
      host: "127.0.0.1"
      count: 3
      packetSize: 56
    expect:
      alive: true
      packetLossPercent:
        lte: 10
      avgLatencyMs:
        lte: 100
      maxLatencyMs:
        lte: 300
      durationMs:
        lte: 5000

  # ========== DNS targets ==========

  # 本机 DNS 解析检查（system 模式）
  - id: "dns-system-localhost"
    name: "本机 DNS 解析"
    type: dns
    group: "DNS"
    dns:
      resolver: system
      name: "localhost"
      family: ipv4
    expect:
      values:
        exact:
          - "127.0.0.1"
      durationMs:
        lte: 200

  # DNS server 拨测（server 模式，A 记录）
  - id: "dns-server-cf"
    name: "Cloudflare DNS A 记录"
    type: dns
    group: "DNS"
    dns:
      resolver: server
      server: "1.1.1.1"
      name: "example.com"
      recordType: A
    expect:
      rcode: ["NOERROR"]
      ttlMin:
        gte: 60
      durationMs:
        lte: 500

  # 负向 DNS 检查（NXDOMAIN）
  - id: "dns-nxdomain-check"
    name: "负向 DNS 检查"
    type: dns
    group: "DNS"
    dns:
      resolver: server
      server: "1.1.1.1"
      name: "this-domain-should-not-exist.example.com"
      recordType: A
    expect:
      rcode: ["NXDOMAIN"]

  # MX 记录检查
  - id: "dns-mx-check"
    name: "MX 记录检查"
    type: dns
    group: "DNS"
    dns:
      resolver: server
      server: "1.1.1.1"
      name: "gmail.com"
      recordType: MX
    expect:
      rcode: ["NOERROR"]

  # ========== UDP targets ==========

  - id: "udp-heartbeat"
    name: "UDP 心跳检测"
    type: udp
    group: "基础设施"
    udp:
      host: "127.0.0.1"
      port: 9000
      payload: "PING"
    expect:
      response:
        - contains: "PONG"
      durationMs:
        lte: 100

  - id: "udp-binary-probe"
    name: "UDP 二进制协议探测"
    type: udp
    group: "基础设施"
    udp:
      host: "127.0.0.1"
      port: 5683
      payload: "400100"
      encoding: hex
      responseEncoding: hex
    expect:
      responseSize:
        gte: 4
      durationMs:
        lte: 200

  - id: "udp-fire-and-forget"
    name: "UDP 发送验证（不等待响应）"
    type: udp
    group: "基础设施"
    udp:
      host: "127.0.0.1"
      port: 514
      payload: "<14>health check"
    expect:
      responded: false

  - id: "llm-openai-probe"
    name: "OpenAI Chat Completions 健康检查"
    type: llm
    group: "AI 服务"
    llm:
      provider: openai
      url: "https://open.bigmodel.cn/api/paas/v4"
      model: "glm-4.7-flash"
      prompt: "Say OK"
      key: "d1e97306540d12bb2f834be961fcacb1.SNBShlCxWYJCx0qZ"
    expect:
      status:
        - 200
      finishReason: "stop"
      output:
        - contains: "OK"

  # ========== WS targets ==========

  - id: "ws-reachability"
    name: "WebSocket 服务可达"
    type: ws
    group: "基础设施"
    ws:
      url: "wss://echo.websocket.org"
    expect:
      durationMs:
        lte: 5000

  - id: "ws-echo-check"
    name: "WebSocket Echo 交互检查"
    type: ws
    group: "基础设施"
    ws:
      url: "wss://echo.websocket.org"
      send: "hello"
      receiveTimeout: 3000
    expect:
      message:
        - contains: "hello"
      durationMs:
        lte: 5000
