#!/usr/bin/env bash
set -uo pipefail

# ──────────────────────────────────────────────
# live_run_v3.sh — MARK Ⅶ 統合起動スクリプト
# ──────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
V3_DIR="$SCRIPT_DIR"

# 最大稼働時間（秒）。これを超えたら自動停止して止め忘れ事故を防ぐ。
# 2026-05-09 追加：1日9時間放置事故対策。
# MARK Ⅶ 正規利用は会議1〜2時間想定なので3時間で十分。長時間使う時は再起動すればよい。
MAX_RUNTIME_SEC=${MAX_RUNTIME_SEC:-10800}  # 3時間

STREAM_PID_FILE="$V3_DIR/.stream.pid"
DAEMON_PID_FILE="$V3_DIR/.daemon_v3.pid"
LOG_DIR="$V3_DIR/logs"
STREAM_LOG="$LOG_DIR/stream_transcriber.log"
DAEMON_LOG="$LOG_DIR/active_daemon.log"

STREAM_SCRIPT="$V3_DIR/stream_transcriber.py"
DAEMON_SCRIPT="$V3_DIR/jarvis_active_daemon.py"

MIRROR_SCRIPT="/Users/rk/.local/jarvis/mirror_to_dashboard.sh"

# ──────────────────────────────────────────────
# ユーティリティ
# ──────────────────────────────────────────────

log() { echo "[$(date '+%H:%M:%S')] $*"; }
err() { echo "[$(date '+%H:%M:%S')] ERROR: $*" >&2; }

pid_alive() {
    local pid="$1"
    [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null
}

read_pid() {
    local f="$1"
    [[ -f "$f" ]] && cat "$f" || echo ""
}

# ──────────────────────────────────────────────
# --stop
# ──────────────────────────────────────────────

do_stop() {
    log "MARK Ⅶ 停止中..."

    local stream_pid daemon_pid
    stream_pid="$(read_pid "$STREAM_PID_FILE")"
    daemon_pid="$(read_pid "$DAEMON_PID_FILE")"

    local stopped=0

    if pid_alive "$stream_pid"; then
        log "stream_transcriber (PID $stream_pid) に SIGINT 送信"
        kill -INT "$stream_pid" 2>/dev/null && stopped=$((stopped + 1))
    else
        log "stream_transcriber: 未起動 or 既に停止済"
    fi

    if pid_alive "$daemon_pid"; then
        log "jarvis_active_daemon (PID $daemon_pid) に SIGINT 送信"
        kill -INT "$daemon_pid" 2>/dev/null && stopped=$((stopped + 1))
    else
        log "jarvis_active_daemon: 未起動 or 既に停止済"
    fi

    # 最大5秒待機
    local wait=0
    while (pid_alive "$stream_pid" || pid_alive "$daemon_pid") && [[ $wait -lt 5 ]]; do
        sleep 1
        wait=$((wait + 1))
    done

    # 残存プロセス強制終了
    if pid_alive "$stream_pid"; then
        log "stream_transcriber 強制終了"
        kill -KILL "$stream_pid" 2>/dev/null || true
    fi
    if pid_alive "$daemon_pid"; then
        log "jarvis_active_daemon 強制終了"
        kill -KILL "$daemon_pid" 2>/dev/null || true
    fi

    rm -f "$STREAM_PID_FILE" "$DAEMON_PID_FILE"
    log "PIDファイル削除済"

    if [[ $stopped -gt 0 ]]; then
        log "MARK Ⅶ 停止完了"
    else
        log "MARK Ⅶ: 停止対象なし（既に停止済）"
    fi
}

# ──────────────────────────────────────────────
# --dry-run
# ──────────────────────────────────────────────

do_dry_run() {
    log "=== MARK Ⅶ dry-run 開始 ==="
    local fail=0

    # Python 確認
    if ! command -v python3 &>/dev/null; then
        err "python3 が見つかりません"
        fail=$((fail + 1))
    else
        log "python3: OK ($(python3 --version 2>&1))"
    fi

    # claude コマンド確認
    if ! command -v claude &>/dev/null; then
        err "claude が見つかりません（Claude Code インストール確認）"
        fail=$((fail + 1))
    else
        log "claude: OK"
    fi

    # whisper-stream 確認
    if ! command -v whisper-stream &>/dev/null; then
        err "whisper-stream が見つかりません → brew install whisper-cpp"
        fail=$((fail + 1))
    else
        log "whisper-stream: OK"
    fi

    # say コマンド確認
    if ! command -v say &>/dev/null; then
        err "say が見つかりません（macOS 専用）"
        fail=$((fail + 1))
    else
        log "say: OK"
    fi

    # スクリプト存在確認
    for f in "$STREAM_SCRIPT" "$DAEMON_SCRIPT"; do
        if [[ -f "$f" ]]; then
            log "$(basename "$f"): OK"
        else
            err "$(basename "$f") が見つかりません（並走Agent未完成の可能性）"
            fail=$((fail + 1))
        fi
    done

    # Python 構文チェック（存在するファイルのみ）
    for f in "$STREAM_SCRIPT" "$DAEMON_SCRIPT"; do
        if [[ -f "$f" ]]; then
            if python3 -m py_compile "$f" 2>/dev/null; then
                log "構文OK: $(basename "$f")"
            else
                err "構文エラー: $(basename "$f")"
                fail=$((fail + 1))
            fi
        fi
    done

    # ログディレクトリ確認
    mkdir -p "$LOG_DIR"
    log "ログディレクトリ: OK ($LOG_DIR)"

    log "=== dry-run 完了: fail=$fail ==="

    if [[ $fail -gt 0 ]]; then
        err "dry-run FAILED ($fail 件のエラー)"
        exit 1
    else
        log "dry-run PASSED — 起動可能"
        exit 0
    fi
}

# ──────────────────────────────────────────────
# シグナルハンドラ（SIGINT / SIGTERM）
# ──────────────────────────────────────────────

cleanup() {
    log "シグナル受信 — MARK Ⅶ 停止シーケンス開始"
    do_stop
    exit 0
}

trap cleanup INT TERM

# ──────────────────────────────────────────────
# 多重起動チェック
# ──────────────────────────────────────────────

check_already_running() {
    local stream_pid daemon_pid
    stream_pid="$(read_pid "$STREAM_PID_FILE")"
    daemon_pid="$(read_pid "$DAEMON_PID_FILE")"

    if pid_alive "$stream_pid"; then
        err "stream_transcriber が既に起動中 (PID $stream_pid)"
        err "停止するには: bash stop_v3.sh"
        exit 1
    fi
    if pid_alive "$daemon_pid"; then
        err "jarvis_active_daemon が既に起動中 (PID $daemon_pid)"
        err "停止するには: bash stop_v3.sh"
        exit 1
    fi

    # 古い PID ファイルがあれば削除
    rm -f "$STREAM_PID_FILE" "$DAEMON_PID_FILE"
}

# ──────────────────────────────────────────────
# 通常起動
# ──────────────────────────────────────────────

do_start() {
    log "=== MARK Ⅶ 起動 ==="

    check_already_running
    mkdir -p "$LOG_DIR"

    # 起動前クリーンアップ（2026-05-07 追加）：
    # state.last_offset が古い transcript サイズで残ってると新規行が
    # 検出されない。毎起動時に transcript と state を整合させる。
    local TRANSCRIPT_FILE="$V3_DIR/live_transcript.txt"
    local STATE_FILE="$V3_DIR/daemon_state_v3.json"
    if [[ -f "$TRANSCRIPT_FILE" ]]; then
        # 古い transcript（前回セッション分）はアーカイブして新規開始
        local archive_name="live_transcript.$(date +%Y%m%d_%H%M%S).txt"
        mv "$TRANSCRIPT_FILE" "$V3_DIR/archives/$archive_name" 2>/dev/null || \
            { mkdir -p "$V3_DIR/archives" && mv "$TRANSCRIPT_FILE" "$V3_DIR/archives/$archive_name"; }
        log "前回 transcript をアーカイブ: archives/$archive_name"
    fi
    : > "$TRANSCRIPT_FILE"
    # state リセット（last_offset=0・前回介入時刻クリア）
    echo '{"last_offset": 0, "last_intervention_at": 0, "started_at": 0, "last_intervention_offset": 0}' > "$STATE_FILE"
    log "transcript と daemon_state をリセット"

    # stream_transcriber 起動
    log "stream_transcriber 起動中..."
    python3 -u "$STREAM_SCRIPT" >> "$STREAM_LOG" 2>&1 &
    local stream_pid=$!
    echo "$stream_pid" > "$STREAM_PID_FILE"
    log "stream_transcriber PID=$stream_pid (ログ: $STREAM_LOG)"

    # 2秒待機
    sleep 2

    # jarvis_active_daemon 起動
    log "jarvis_active_daemon 起動中..."
    python3 -u "$DAEMON_SCRIPT" >> "$DAEMON_LOG" 2>&1 &
    local daemon_pid=$!
    echo "$daemon_pid" > "$DAEMON_PID_FILE"
    log "jarvis_active_daemon PID=$daemon_pid (ログ: $DAEMON_LOG)"

    # 5秒後に生存確認
    log "5秒後にプロセス生存確認..."
    sleep 5

    local all_ok=1

    if ! pid_alive "$stream_pid"; then
        err "stream_transcriber が異常終了しました"
        echo "--- stream_transcriber ログ末尾 ---" >&2
        tail -20 "$STREAM_LOG" >&2 2>/dev/null || true
        all_ok=0
    else
        log "stream_transcriber: 生存確認 OK"
    fi

    if ! pid_alive "$daemon_pid"; then
        err "jarvis_active_daemon が異常終了しました"
        echo "--- jarvis_active_daemon ログ末尾 ---" >&2
        tail -20 "$DAEMON_LOG" >&2 2>/dev/null || true
        all_ok=0
    else
        log "jarvis_active_daemon: 生存確認 OK"
    fi

    if [[ $all_ok -eq 0 ]]; then
        err "起動失敗 — 両プロセスを停止して終了"
        do_stop
        exit 1
    fi

    log "MARK Ⅶ 起動完了"
    log "  stream_transcriber  PID=$stream_pid"
    log "  jarvis_active_daemon PID=$daemon_pid"
    log "停止するには: bash stop_v3.sh"

    # dashboard キャッシュ刷新
    if [[ -f "$MIRROR_SCRIPT" ]]; then
        log "dashboard 刷新中..."
        bash "$MIRROR_SCRIPT" 2>/dev/null || log "(mirror スキップ — エラー無視)"
    else
        log "mirror_to_dashboard.sh 未検出 — dashboard 刷新スキップ"
    fi

    # 両プロセスが生きている間は待機（trapで終了）
    # 最大稼働時間ガード：MAX_RUNTIME_SEC 経過で自動停止（止め忘れ防止）
    local started_at=$(date +%s)
    while pid_alive "$stream_pid" || pid_alive "$daemon_pid"; do
        sleep 30
        local elapsed=$(( $(date +%s) - started_at ))
        if [[ $elapsed -ge $MAX_RUNTIME_SEC ]]; then
            log "最大稼働時間 ${MAX_RUNTIME_SEC}秒 到達 — 自動停止"
            do_stop
            exit 0
        fi
    done
}

# ──────────────────────────────────────────────
# エントリポイント
# ──────────────────────────────────────────────

case "${1:-}" in
    --stop)
        do_stop
        ;;
    --dry-run)
        do_dry_run
        ;;
    "")
        do_start
        ;;
    *)
        echo "使い方: $(basename "$0") [--dry-run | --stop]" >&2
        exit 1
        ;;
esac
