#!/bin/bash
# Pilot Studio 開不起來時的救援腳本（升級戶專用，重裝之前先跑這個）
#   curl -fsSL https://pilot.wow.to/fix-pilot.sh | bash
# 只做四件事，每件都先備份：
#   1) 把 profile 裡「bundle 已經提供」的重複 insert 註解掉（升級後開機即掛的主因）
#   2) 插件副本：包內有同版本的，以包內（修好的）為準
#   3) 核心套件副本：profile 內版本與包內不同的 @deepseek-ai/* 改連包內那份
#      （插件把它們當 dependency 拉進舊版，舊版少了 remote host → 整個 /api/<ns>/* 靜默 404，
#       症狀是「設定→模型 載入提供方目錄失敗」，而宿主 log 完全乾淨）
#   4) settings.yaml 的 llm-deepseek.baseURL 補上 /anthropic（不然模型呼叫 404）
# 路徑可用 PILOT_APP／DSH_HOME 覆寫（沙箱測試用），預設＝實機。
set -u
APP="${PILOT_APP:-/Applications/Pilot Studio.app}"
R="$APP/Contents/Resources/app"
H="${DSH_HOME:-$HOME/Library/Application Support/dsh-desktop/harness}"
P="$H/profiles/web"
[ -d "$R/node_modules" ] || { echo "找不到 App：$APP"; exit 1; }
[ -d "$P" ] || { echo "找不到 profile：$P（這台沒裝過或已重置，重下 DMG 就好）"; exit 1; }
TS=$(date +%Y%m%d-%H%M%S)

python3 - "$P" "$R" "$H" "$TS" <<'PY'
import json, pathlib, re, shutil, sys
P, R, H, TS = map(pathlib.Path, sys.argv[1:5])

# 1) 撞名 insert：bundle 已提供的，profile patch 裡的同名 insert 註解掉（連 - insert: 父項一起）
patch = P / 'cordis.patch.yml'
bundles = set(json.loads((P / 'package.json').read_text())['dsh']['profile']['bundles'])
lines = patch.read_text().split('\n')
out, i, killed = [], 0, []
while i < len(lines):
    line = lines[i]
    if line.startswith('- insert:'):
        j = i + 1
        ids = []
        while j < len(lines) and lines[j].startswith('    '):
            m = re.match(r'\s+- id:\s*(\S+)', lines[j])
            if m: ids.append((j, m.group(1)))
            j += 1
        if ids and all(x[1] in bundles for x in ids):
            out.append('# [救援：這個 insert 由內建 bundle 提供，重複會讓宿主開不起來]')
            for k in range(i, j):
                out.append('# ' + lines[k])
            killed += [x[1] for x in ids]
            i = j
            continue
    out.append(line); i += 1
if killed:
    shutil.copy2(patch, patch.parent / f'{patch.name}.bak-fix-{TS}')
    patch.write_text('\n'.join(out))
print('1) 註解掉重複 insert：', killed or '無')

# 2) 插件副本：同版本 -> 以包內為準（版本不同＝別人的東西，留著不動）
fixed = []
for name in sorted(bundles):
    a, b = R / 'node_modules' / name, P / 'node_modules' / name
    if not (a.is_dir() and b.is_dir()):
        continue
    try:
        va = json.loads((a / 'package.json').read_text())['version']
        vb = json.loads((b / 'package.json').read_text())['version']
    except Exception:
        continue
    if va != vb:
        print(f'   {name}: 版本不同（包內 {va} / profile {vb}）→ 留著不動')
        continue
    # lib/ 佈局假設會漏掉沒有 lib/ 的插件（dsh-dock 檔在根目錄 → all([])=True → 永不換）；
    # 2026-09-22：改成整包 runtime 檔比對（跳過 node_modules/.git/screenshots）
    SKIP = {'node_modules', '.git', 'screenshots'}
    def digest(root):
        out = {}
        for p in sorted(root.rglob('*')):
            if set(p.relative_to(root).parts) & SKIP:
                continue
            if p.is_file() and not p.is_symlink():
                out[str(p.relative_to(root))] = p.read_bytes()
        return out
    da, db = digest(a), digest(b)
    same = da == db
    if not same:
        shutil.move(str(b), f'{b}.bak-pristine-{TS}')
        shutil.copytree(a, b, symlinks=True)
        fixed.append(name)
print('2) 換成包內修好的插件：', fixed or '無')

# 3) 核心套件副本：版本與包內不同 -> 搬走 + 連到包內那份（同名但舊的會蓋掉 harness 自己的）
shadow = []
scope, packed = P / 'node_modules' / '@deepseek-ai', R / 'node_modules' / '@deepseek-ai'
if scope.is_dir() and packed.is_dir():
    for d in sorted(scope.iterdir()):
        a = packed / d.name
        if '.bak-' in d.name or not (a / 'package.json').exists():
            continue
        try:
            va = json.loads((a / 'package.json').read_text())['version']
            vb = json.loads((d / 'package.json').read_text())['version'] if (d / 'package.json').is_file() else None
        except Exception:
            continue
        if vb is None or va == vb:
            continue
        shutil.move(str(d), f'{d}.bak-shadow-{TS}')
        d.symlink_to(a, target_is_directory=True)
        shadow.append(f'{d.name}: {vb} -> {va}')
print('3) 核心套件改連包內版：', shadow or '無')

# 4) baseURL 補 /anthropic
s = H / 'settings.yaml'
if s.exists():
    t = s.read_text()
    if re.search(r'(?m)^  baseURL: https://api\.deepseek\.com\s*$', t):
        shutil.copy2(s, s.parent / f'{s.name}.bak-fix-{TS}')
        s.write_text(re.sub(r'(?m)^  baseURL: https://api\.deepseek\.com\s*$',
                            '  baseURL: https://api.deepseek.com/anthropic', t))
        print('3) baseURL 已補 /anthropic')
    else:
        print('3) baseURL 不需修')
PY

echo "完成。重開 Pilot Studio 看看。"
