// 回傳 Markdown 格式開發指引
// Requirements: 11.1, 11.2, 11.3

export function getGuide(): string {
  return `# u6u Component Authoring Guide

## 概覽

u6u 零件是以 WASI preview1 格式編譯的 WebAssembly 模組，唯一合法的 I/O 模型是 **stdin/stdout JSON**。

---

## TinyGo 白名單 {#tinygo-whitelist}

第一波內部零件使用 TinyGo 開發。**只允許**以下 import：

\`\`\`go
import (
    "os"             // 只用 os.Stdin / os.Stdout / os.Stderr
    "io"             // io.ReadAll(os.Stdin)
    "encoding/json"  // json.Unmarshal / json.Marshal
)
\`\`\`

### 允許的操作

- \`io.ReadAll(os.Stdin)\` 讀取 input JSON
- \`json.Unmarshal\` 解析 input
- \`json.Marshal\` + \`os.Stdout.Write\` 輸出 output JSON
- 基本型別操作（string、int64、float64、bool、[]byte、map[string]interface{}）
- 錯誤用 stdout 輸出：\`{"error": "說明"}\`，不要 panic

---

## 禁止行為 {#forbidden-behaviors}

以下行為會導致沙盒驗收失敗：

- **網路 syscall**：\`net/*\`、\`sock_connect\`、\`sock_accept\` 等
- **檔案系統 syscall**：\`os.Open\`、\`os.Create\`、\`path_open\` 等
- **goroutine / channel**：WASM 環境不支援
- **syscall.*\`**：任何直接 syscall
- **第三方 module**：只用標準庫
- **打包 runtime**：不得打包 QuickJS、Node.js 等
- **超過 2MB**：體積上限 2048KB
- **混合前後端邏輯**：一個零件只做一件事

---

## I/O 模型 {#io-model}

唯一合法的 I/O 模型：\`stdin_stdout_json\`

\`\`\`
stdin  → JSON.stringify(input)  → 零件讀取
stdout ← JSON.stringify(output) ← 零件輸出
\`\`\`

---

## TinyGo 最小可運行範例 {#tinygo-example}

\`\`\`go
package main

import (
    "encoding/json"
    "io"
    "os"
)

type Input struct {
    JsonString string \`json:"json_string"\`
}

type Output struct {
    Valid bool   \`json:"valid"\`
    Error string \`json:"error,omitempty"\`
}

func main() {
    data, err := io.ReadAll(os.Stdin)
    if err != nil {
        writeError("讀取 stdin 失敗: " + err.Error())
        return
    }

    var input Input
    if err := json.Unmarshal(data, &input); err != nil {
        writeError("解析 input JSON 失敗: " + err.Error())
        return
    }

    var result interface{}
    valid := json.Unmarshal([]byte(input.JsonString), &result) == nil

    out := Output{Valid: valid}
    if !valid {
        out.Error = "不合法的 JSON 格式"
    }

    outBytes, _ := json.Marshal(out)
    os.Stdout.Write(outBytes)
}

func writeError(msg string) {
    out, _ := json.Marshal(map[string]string{"error": msg})
    os.Stdout.Write(out)
}
\`\`\`

---

## component.contract.yaml 完整範例 {#contract-example}

\`\`\`yaml
canonical_id: "validate_json"
display_name: "JSON 格式驗證器"
category: "logic"
version: "v1"
wasi_target: "preview1"
stability: "floating"

runtime_compat:
  - "cf-workers"
  - "workerd"
  - "wazero"

constraints:
  max_size_kb: 2048
  max_cold_start_ms: 50
  no_network_syscall: true
  io_model: "stdin_stdout_json"

input_schema:
  type: object
  required: ["json_string"]
  properties:
    json_string:
      type: string
      description: "待驗證的 JSON 字串"

output_schema:
  type: object
  properties:
    valid:
      type: boolean
    error:
      type: string

gherkin_tests:
  - scenario: "合法 JSON 通過驗證"
    given: '{"json_string":"{\\"key\\":\\"value\\"}"}'
    then_contains: '{"valid":true}'
  - scenario: "非法 JSON 回傳錯誤"
    given: '{"json_string":"not-json"}'
    then_contains: '{"valid":false,"error":'

tags: ["validation", "json", "utility"]
description: "驗證輸入字串是否為合法 JSON 格式"
\`\`\`

---

## 本地測試指令 {#local-testing}

使用 \`wasmtime\` 在本地測試零件：

\`\`\`bash
# 編譯（TinyGo）
tinygo build -o validate_json.wasm -target wasi ./main.go

# 測試 happy path
echo '{"json_string":"{}"}' | wasmtime validate_json.wasm
# 預期輸出：{"valid":true}

# 測試 error path
echo '{"json_string":"not-json"}' | wasmtime validate_json.wasm
# 預期輸出：{"valid":false,"error":"..."}
\`\`\`

---

## syscall 限制 {#syscall-constraints}

沙盒驗收會掃描 .wasm binary 中的 import，以下 syscall 一律拒絕：

- \`sock_connect\`、\`sock_accept\`、\`sock_recv\`、\`sock_send\`、\`sock_shutdown\`
- \`fd_open\`、\`path_open\`、\`path_create_directory\`、\`path_remove_directory\`
- \`path_rename\`、\`path_unlink_file\`、\`path_filestat_get\`

---

## 常見錯誤與解法 {#common-errors}

| 錯誤 | 原因 | 解法 |
|---|---|---|
| \`size_check 失敗\` | .wasm 超過 2048KB | 移除不必要的依賴，使用 TinyGo 而非 Go |
| \`syscall_scan 失敗\` | 含有網路/檔案 syscall | 移除 \`net/*\`、\`os.Open\` 等 import |
| \`gherkin_tests 失敗\` | 輸出不符合預期 | 確認 stdout 輸出為合法 JSON |
| \`contract 驗證失敗\` | 缺少必填欄位 | 參考上方 contract 範例補齊欄位 |

---

## contract.yaml JSON Schema {#contract-schema}

\`\`\`json
{
  "type": "object",
  "required": ["canonical_id", "display_name", "category", "version", "wasi_target", "stability", "runtime_compat", "constraints", "input_schema", "output_schema", "gherkin_tests"],
  "properties": {
    "canonical_id": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
    "display_name": { "type": "string" },
    "category": { "type": "string", "enum": ["logic", "api", "ui", "style", "anim"] },
    "version": { "type": "string", "pattern": "^v\\\\d+$" },
    "wasi_target": { "type": "string", "enum": ["preview1"] },
    "stability": { "type": "string", "enum": ["floating", "stable", "pinned"] },
    "runtime_compat": { "type": "array", "items": { "type": "string", "enum": ["cf-workers", "workerd", "wazero"] }, "minItems": 1 },
    "constraints": {
      "type": "object",
      "required": ["max_size_kb", "max_cold_start_ms", "no_network_syscall", "io_model"],
      "properties": {
        "max_size_kb": { "type": "number", "maximum": 2048 },
        "max_cold_start_ms": { "type": "number", "maximum": 50 },
        "no_network_syscall": { "type": "boolean" },
        "io_model": { "type": "string", "enum": ["stdin_stdout_json"] }
      }
    },
    "input_schema": { "type": "object" },
    "output_schema": { "type": "object" },
    "gherkin_tests": { "type": "array", "minItems": 2 }
  }
}
\`\`\`
`;
}
