#!/usr/bin/env bash
# live_run.sh — Phase 1 Lv2 Jarvis常駐デーモン 統合起動スクリプト
# 役割: recorder.py と watcher.py を並列バックグラウンド起動し Ctrl+C で graceful stop
set -uo pipefail

# --------------------------------------------------------
# パス解決
# --------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RECORDER="$SCRIPT_DIR/recorder.py"
WATCHER="$SCRIPT_DIR/watcher.py"
LOG_DIR="$SCRIPT_DIR/logs"
RECORDER_LOG="$LOG_DIR/recorder.log"
WATCHER_LOG="$LOG_DIR/watcher.log"
RECORDER_PID_FILE="$SCRIPT_DIR/.recorder.pid"
WATCHER_PID_FILE="$SCRIPT_DIR/.watcher.pid"

PYTHON="${PYTHON:-python3}"

# --------------------------------------------------------
# ヘルパー
# --------------------------------------------------------
log() { echo "[live_run] $*"; }
err() { echo "[live_run] ERROR: $*" >&2; }

require_file() {
    if [[ ! -f "$1" ]]; then
        err "$1 が見つかりません"
        exit 1
    fi
}

# --------------------------------------------------------
# --stop モード
# --------------------------------------------------------
if [[ "${1:-}" == "--stop" ]]; then
    stopped=0
    for pidfile in "$RECORDER_PID_FILE" "$WATCHER_PID_FILE"; do
        if [[ -f "$pidfile" ]]; then
            pid="$(cat "$pidfile")"
            if kill -0 "$pid" 2>/dev/null; then
                kill -INT "$pid" && log "停止シグナル送信: PID $pid ($(basename "$pidfile"))"
                stopped=$((stopped + 1))
            else
                log "PID $pid はすでに終了済み"
            fi
            rm -f "$pidfile"
        else
            log "$pidfile が存在しない（すでに停止済み？）"
        fi
    done
    [[ $stopped -gt 0 ]] && log "停止完了" || log "停止対象なし"
    exit 0
fi

# --------------------------------------------------------
# dry-run サブ関数（recorder / watcher 両方テスト）
# --------------------------------------------------------
run_dry_run() {
    log "--- dry-run テスト開始 ---"
    require_file "$RECORDER"
    require_file "$WATCHER"

    if "$PYTHON" "$RECORDER" --dry-run; then
        log "recorder.py dry-run OK"
    else
        err "recorder.py dry-run 失敗 → abort"
        return 1
    fi

    if "$PYTHON" "$WATCHER" --dry-run; then
        log "watcher.py dry-run OK"
    else
        err "watcher.py dry-run 失敗 → abort"
        return 1
    fi

    log "--- dry-run テスト完了 ---"
    return 0
}

# --------------------------------------------------------
# --dry-run モード（テストのみ・起動しない）
# --------------------------------------------------------
if [[ "${1:-}" == "--dry-run" ]]; then
    run_dry_run
    exit $?
fi

# --------------------------------------------------------
# 多重起動チェック
# --------------------------------------------------------
for pidfile in "$RECORDER_PID_FILE" "$WATCHER_PID_FILE"; do
    if [[ -f "$pidfile" ]]; then
        existing_pid="$(cat "$pidfile")"
        if kill -0 "$existing_pid" 2>/dev/null; then
            err "すでに起動中です (PID $existing_pid in $pidfile)。--stop で止めてから再起動してください"
            exit 1
        else
            log "古い PID ファイルを削除: $pidfile"
            rm -f "$pidfile"
        fi
    fi
done

# --------------------------------------------------------
# 事前 dry-run（起動前必須チェック）
# --------------------------------------------------------
run_dry_run || exit 1

# --------------------------------------------------------
# ログディレクトリ作成
# --------------------------------------------------------
mkdir -p "$LOG_DIR"

# --------------------------------------------------------
# クリーンアップ関数（SIGINT / SIGTERM）
# --------------------------------------------------------
cleanup() {
    log "シャットダウン中..."
    for pidfile in "$WATCHER_PID_FILE" "$RECORDER_PID_FILE"; do
        if [[ -f "$pidfile" ]]; then
            pid="$(cat "$pidfile")"
            if kill -0 "$pid" 2>/dev/null; then
                kill -INT "$pid"
                # 最大5秒待機
                for i in $(seq 1 5); do
                    kill -0 "$pid" 2>/dev/null || break
                    sleep 1
                done
                # 残存なら強制終了
                if kill -0 "$pid" 2>/dev/null; then
                    kill -TERM "$pid" 2>/dev/null || true
                fi
            fi
            rm -f "$pidfile"
        fi
    done
    log "停止完了"
    exit 0
}

trap cleanup SIGINT SIGTERM

# --------------------------------------------------------
# watcher.py 起動（先に監視を立ち上げる）
# --------------------------------------------------------
log "watcher.py を起動中..."
"$PYTHON" "$WATCHER" >> "$WATCHER_LOG" 2>&1 &
WATCHER_PID=$!
echo "$WATCHER_PID" > "$WATCHER_PID_FILE"
log "watcher.py PID: $WATCHER_PID"

sleep 1

# --------------------------------------------------------
# recorder.py 起動
# --------------------------------------------------------
log "recorder.py を起動中..."
"$PYTHON" "$RECORDER" >> "$RECORDER_LOG" 2>&1 &
RECORDER_PID=$!
echo "$RECORDER_PID" > "$RECORDER_PID_FILE"
log "recorder.py PID: $RECORDER_PID"

# --------------------------------------------------------
# 5秒後 生存確認
# --------------------------------------------------------
sleep 5

any_dead=0

if ! kill -0 "$WATCHER_PID" 2>/dev/null; then
    err "watcher.py が5秒以内に終了しました。ログ末尾:"
    tail -20 "$WATCHER_LOG" >&2
    any_dead=1
fi

if ! kill -0 "$RECORDER_PID" 2>/dev/null; then
    err "recorder.py が5秒以内に終了しました。ログ末尾:"
    tail -20 "$RECORDER_LOG" >&2
    any_dead=1
fi

if [[ $any_dead -eq 1 ]]; then
    err "起動失敗。クリーンアップします"
    cleanup
    exit 1
fi

log "両プロセス起動確認 OK"
log "停止: Ctrl+C または bash live_run.sh --stop"

# --------------------------------------------------------
# 両プロセスが終わるまで待機（どちらかが死んだら終了）
# --------------------------------------------------------
wait -n 2>/dev/null || {
    # wait -n が使えない bash 3 系対策
    while kill -0 "$RECORDER_PID" 2>/dev/null && kill -0 "$WATCHER_PID" 2>/dev/null; do
        sleep 2
    done
}

err "プロセスが予期せず終了しました"
cleanup
exit 1
