#!/bin/bash
# 並列実装マネージャー

# ログ関数の定義
log_info() {
    echo "[INFO] $*" >&2
}

log_error() {
    echo "[ERROR] $*" >&2
}

log_success() {
    echo "[SUCCESS] $*" >&2
}

# スクリプトのディレクトリを取得
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# プロジェクトディレクトリを設定（scriptsの2階層上）
PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
export PROJECT_DIR

source "$SCRIPT_DIR/../common/config.sh" 2>/dev/null || true
source "$SCRIPT_DIR/../common/utils.sh" 2>/dev/null || true

# 並列実装セッション情報を保存するディレクトリ
# 実行元のディレクトリに保存
PARALLEL_SESSION_DIR="${CALLER_PWD:-$(pwd)}/logs/parallel_sessions"
mkdir -p "$PARALLEL_SESSION_DIR"

# 複雑度に基づいてワーカー数を決定
determine_worker_count() {
    local complexity="$1"
    local requested_count="${2:-0}"
    
    # リクエストされた数が指定されていればそれを使用
    if [ "$requested_count" -gt 0 ]; then
        echo "$requested_count"
        return
    fi
    
    # 複雑度に基づいてデフォルト数を決定
    case "$complexity" in
        "simple")
            echo "1"  # Bossなし、Worker1体のみ
            ;;
        "medium")
            echo "3"  # Boss + Worker3体
            ;;
        "complex")
            echo "5"  # Boss + Worker5体
            ;;
        *)
            echo "3"  # デフォルト
            ;;
    esac
}

# 並列実装セッションを開始
start_parallel_implementation() {
    local prompt="$1"
    local worker_count="${2:-3}"
    local complexity="${3:-medium}"
    local skip_review="${4:-false}"  # skipオプション: trueで自動マージ
    local use_new_terminal="${5:-true}"
    local agent_type="${6:-claude}"  # エージェントタイプ: claudeまたはgemini
    
    log_info "並列実装開始: ワーカー数=$worker_count, 複雑度=$complexity"
    
    # ワーカー数を決定
    worker_count=$(determine_worker_count "$complexity" "$worker_count")
    
    # タイムスタンプとセッションID（ミリ秒とランダム値を含む）
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local random_suffix=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 4 | head -n 1)
    local session_id="parallel_${timestamp}_${random_suffix}"
    
    # 新しい端末で専用tmuxセッションを作成
    if [ "$use_new_terminal" = "true" ]; then
        log_info "新しい端末で専用tmuxセッションを作成中..."
        # 実行元のディレクトリを渡す
        local working_dir="${CALLER_PWD:-$(pwd)}"
        log_info "作業ディレクトリ: $working_dir"
        local tmux_session=$("$SCRIPT_DIR/terminal_launcher.sh" create-parallel "impl" "$worker_count" "$working_dir")
        
        if [ -z "$tmux_session" ]; then
            log_error "tmuxセッションの作成に失敗しました"
            return 1
        fi
        
        # 新しいセッション名を使用
        MULTIAGENT_SESSION="$tmux_session"
        export MULTIAGENT_SESSION
        
        # セッションが完全に起動するまで待機
        sleep 2
    fi
    
    # セッション情報を保存
    local session_file="${PARALLEL_SESSION_DIR}/${session_id}.json"
    
    # Worktreeを作成
    log_info "Worktree作成中..."
    # CALLER_PWDが設定されていない場合のみpwdを使用
    if [ -z "$CALLER_PWD" ]; then
        export CALLER_PWD="$(pwd)"
    fi
    local worktree_info=$("$SCRIPT_DIR/worktree_manager.sh" create-parallel "$session_id" "$worker_count")
    
    if [ $? -ne 0 ] || [ -z "$worktree_info" ]; then
        log_error "Worktree作成失敗"
        return 1
    fi
    
    # worktree_infoが有効なJSONか確認
    if ! echo "$worktree_info" | jq . >/dev/null 2>&1; then
        log_error "Worktree情報が不正なJSON形式です: $worktree_info"
        return 1
    fi
    
    # Worktree情報を解析
    local boss_branch="boss_${session_id}"
    # Bossは実行元のディレクトリで実行（NPX経由でも正しく動作）
    local boss_path="${CALLER_PWD:-$(pwd)}"
    
    # Bossが必要かどうか判定
    local needs_boss=true
    if [ "$complexity" = "simple" ] && [ "$worker_count" -eq 1 ]; then
        needs_boss=false
    fi
    
    # ペインを準備
    local boss_pane=""
    local worker_panes=()
    local start_pane=0
    
    if [ "$needs_boss" = "true" ]; then
        boss_pane="${MULTIAGENT_SESSION}:0.0"
        start_pane=1
    fi
    
    # Workerペインを割り当て
    if [ "$needs_boss" = "true" ]; then
        for i in $(seq 1 $worker_count); do
            worker_panes+=("${MULTIAGENT_SESSION}:0.$i")
        done
    else
        worker_panes+=("${MULTIAGENT_SESSION}:0.0")
    fi
    
    # セッション情報を保存
    # worker_panesの配列を安全に生成
    local worker_panes_json=""
    if [ ${#worker_panes[@]} -gt 0 ]; then
        worker_panes_json=$(printf '"%s",' "${worker_panes[@]}" | sed 's/,$//')
    fi
    
    # worktree_infoを安全にJSON化
    local worktree_info_json="{}"
    if [ -n "$worktree_info" ]; then
        worktree_info_json=$(echo "$worktree_info" | jq -c . 2>/dev/null || echo "{}")
    fi
    
    cat > "$session_file" <<EOF
{
    "session_id": "$session_id",
    "timestamp": "$timestamp",
    "prompt": $(echo "$prompt" | jq -R -s .),
    "worker_count": $worker_count,
    "complexity": "$complexity",
    "skip_review": $skip_review,
    "needs_boss": $needs_boss,
    "boss_pane": "$boss_pane",
    "worker_panes": [$worker_panes_json],
    "worktree_info": $worktree_info_json,
    "tmux_session": "${MULTIAGENT_SESSION}",
    "use_new_terminal": $use_new_terminal,
    "agent_type": "$agent_type",
    "status": "initializing"
}
EOF
    
    # Worker情報を先に準備（Boss用プロンプトのため）
    local worker_branches=()
    if [ -n "$worktree_info" ]; then
        # jqを使って安全に配列を抽出
        local branches_json=$(echo "$worktree_info" | jq -r '.worker_branches[]' 2>/dev/null)
        if [ -n "$branches_json" ]; then
            while IFS= read -r branch; do
                worker_branches+=("$branch")
            done <<< "$branches_json"
        fi
    fi
    
    # worker_branchesが空の場合のフォールバック
    if [ ${#worker_branches[@]} -eq 0 ]; then
        log_error "Worker branches not found in worktree info"
        # デフォルトのブランチ名を生成
        for i in $(seq 1 $worker_count); do
            worker_branches+=("worker${i}_${session_id}")
        done
    fi
    
    # Bossが必要な場合は最初に起動
    if [ "$needs_boss" = "true" ]; then
        log_info "Boss準備中 (ペイン: $boss_pane)"
        
        # Bossは実行元ディレクトリで実行
        local boss_working_dir="${CALLER_PWD:-$(pwd)}"
        log_info "Boss作業ディレクトリ: $boss_working_dir"
        tmux send-keys -t "$boss_pane" "cd '$boss_working_dir'" C-m
        sleep 0.3
        
        # Boss用のプロンプトメッセージを準備
        local boss_prompt="【並列実装タスク - Boss】

元のタスク:
$prompt

あなたはBossとして以下の役割を担います:
1. 全てのWorkerから「Worker〇 実装完了」のメッセージを受信するまで待機
2. 全Worker完了後、各実装を評価
3. 最良の実装を選択、または良い点を組み合わせて統合
4. 必要に応じてWorkerに改善指示

Worker情報:
$(for i in "${!worker_panes[@]}"; do
    echo "- Worker $((i+1)): ${worker_branches[$i]}"
    echo "  パス: ${boss_working_dir}/worktrees/${worker_branches[$i]}"
done)

重要：
- 全てのWorkerから「実装完了」の報告を受け取るまで評価を開始しないでください
- Workerからの報告は画面に「Worker1 実装完了」「Worker2 実装完了」のような形式で表示されます

評価基準:
- コード品質
- 要件の充足度
- パフォーマンス
- 保守性

"
        # autoMerge設定に応じて統合方法を追加
        if [ "$skip_review" = "true" ]; then
            boss_prompt+="統合方法（自動統合モード）:
【重要】評価完了後、必ず以下の手順でmasterブランチにマージしてください：

1. 各Workerの実装を評価（worktreeパスを使用して直接ファイルを読む）
2. 最良のWorkerブランチを選択
3. 以下のコマンドでマージ（Bashツールを使用）:
   git checkout master
   git merge --no-ff <選択したWorkerブランチ> -m \"自動統合: <選択理由>\"
   git log --oneline -1

注意: 
- あなたは既に${boss_working_dir}にいるので、直接gitコマンドを実行できます
- 統合版を作成する場合は、masterブランチで直接作成してコミットしてください
- マージしないとタスクは完了になりません

"
        else
            boss_prompt+="統合方法（手動統合モード）:
- 評価結果を提示し、どのWorkerの実装が最良かを報告してください
- マージは以下のコマンドで手動実行可能であることを案内:
  git checkout master
  git merge --no-ff <選択したWorkerブランチ>

"
        fi
        
        boss_prompt+="完了時は音を鳴らして通知してください。"
        
        # Bossのエージェント起動とプロンプト送信（順次実行）
        local agent_manager="${SCRIPT_DIR}/../agent_tools/agent_manager.sh"
        local auth_helper="${SCRIPT_DIR}/../agent_tools/auth_helper.sh"
        local pane_controller="${SCRIPT_DIR}/../agent_tools/pane_controller.sh"
        
        if [ -f "$agent_manager" ] && [ -f "$auth_helper" ]; then
            local boss_pane_number="${boss_pane##*.}"
            log_info "Boss用$agent_typeを起動中 (セッション: ${MULTIAGENT_SESSION}, ペイン番号: $boss_pane_number)"
            
            # 環境変数を設定
            export TMUX_SESSION="${MULTIAGENT_SESSION}"
            export CLAUDE_NO_BROWSER=1
            
            # エージェント起動
            if ! "$agent_manager" start "$boss_pane_number" "$agent_type"; then
                log_error "Boss エージェント起動コマンド失敗"
            else
                # 起動処理が開始されるまで少し待つ
                sleep 1
                
                # auth_helper.shを使って起動完了を待つ
                log_info "Boss 起動待機中..."
                local retry_count=0
                local max_retries=3
                local startup_success=false
                
                while [ $retry_count -lt $max_retries ]; do
                    if TMUX_SESSION="${MULTIAGENT_SESSION}" "$auth_helper" wait "$boss_pane_number" 90 "$agent_type"; then
                        log_success "Boss 起動完了確認"
                        startup_success=true
                        break
                    else
                        retry_count=$((retry_count + 1))
                        if [ $retry_count -lt $max_retries ]; then
                            log_warn "Boss 起動確認失敗 (リトライ $retry_count/$max_retries)"
                            sleep 2
                        fi
                    fi
                done
                
                if [ "$startup_success" = "true" ]; then
                    # 起動完了後、すぐにタスクを送信
                    log_info "Boss にタスクを送信中..."
                    if ! "$pane_controller" send "$boss_pane_number" "$boss_prompt"; then
                        log_error "Boss タスク送信失敗"
                    else
                        log_success "Boss タスク送信完了"
                    fi
                else
                    log_error "Boss 起動失敗（最大リトライ回数超過）"
                fi
            fi
        else
            log_error "必要なスクリプトが見つかりません: agent_manager.sh または auth_helper.sh"
        fi
    fi
    
    # Workerを起動
    log_info "Worker起動中..."
    
    # 各Workerを順次起動（バックグラウンドではなく順番に実行）
    for i in "${!worker_panes[@]}"; do
        local pane="${worker_panes[$i]}"
        local branch="${worker_branches[$i]}"
        # Worktreeのパスは実行元ディレクトリからの相対パス
        local base_dir="${CALLER_PWD:-$(pwd)}"
        local worktree_path="${base_dir}/worktrees/${branch}"
        
        log_info "Worker $((i+1)) 起動処理開始 (ペイン: $pane, ブランチ: $branch, エージェント: $agent_type)"
        
        # Workerディレクトリに移動
        tmux send-keys -t "$pane" "cd '$worktree_path'" C-m
        sleep 0.3  # cdコマンドの完了を確実に待つ
        
        # Worker用のプロンプトメッセージを準備
        local worker_prompt="【並列実装タスク - Worker $((i+1))】

$prompt

注意事項:
- 他のWorkerとは独立して実装してください
- このディレクトリ ($worktree_path) で作業してください
- 実装が完了したら、Bashツールで以下のコマンドを実行してBossに報告してください：
  TMUX_SESSION=${MULTIAGENT_SESSION} ${SCRIPT_DIR}/../agent_tools/pane_controller.sh send 0 \"Worker$((i+1)) 実装完了\""
        
        # エージェント起動とプロンプト送信（順次実行）
        # agent_manager.shのパスを正しく設定
        local agent_manager="${SCRIPT_DIR}/../agent_tools/agent_manager.sh"
        local auth_helper="${SCRIPT_DIR}/../agent_tools/auth_helper.sh"
        local pane_controller="${SCRIPT_DIR}/../agent_tools/pane_controller.sh"
        
        if [ -f "$agent_manager" ] && [ -f "$auth_helper" ]; then
            # ペイン番号を抽出 (例: "parallel_impl_20250705_142530:0.1" -> "1")
            local pane_number="${pane##*.}"
            log_info "$agent_type を起動中 (セッション: ${MULTIAGENT_SESSION}, ペイン番号: $pane_number)"
            
            # エージェント起動（環境変数を設定して実行）
            export TMUX_SESSION="${MULTIAGENT_SESSION}"
            export CLAUDE_NO_BROWSER=1
            
            # エージェント起動コマンドを実行
            if ! "$agent_manager" start "$pane_number" "$agent_type"; then
                log_error "Worker $((i+1)) エージェント起動コマンド失敗"
                continue
            fi
            
            # 起動処理が開始されるまで少し待つ
            sleep 2
            
            # auth_helper.shを使って起動完了を待つ（タイムアウトを90秒に増加）
            log_info "Worker $((i+1)) 起動待機中..."
            local retry_count=0
            local max_retries=3
            local startup_success=false
            
            while [ $retry_count -lt $max_retries ]; do
                if TMUX_SESSION="${MULTIAGENT_SESSION}" "$auth_helper" wait "$pane_number" 90 "$agent_type"; then
                    log_success "Worker $((i+1)) 起動完了確認"
                    startup_success=true
                    break
                else
                    retry_count=$((retry_count + 1))
                    if [ $retry_count -lt $max_retries ]; then
                        log_warn "Worker $((i+1)) 起動確認失敗 (リトライ $retry_count/$max_retries)"
                        sleep 2
                    fi
                fi
            done
            
            if [ "$startup_success" = "true" ]; then
                # 起動完了後、すぐにタスクを送信
                log_info "Worker $((i+1)) にタスクを送信中..."
                if ! "$pane_controller" send "$pane_number" "$worker_prompt"; then
                    log_error "Worker $((i+1)) タスク送信失敗"
                else
                    log_success "Worker $((i+1)) タスク送信完了"
                fi
                
                # 次のWorkerを起動する前に少し待つ（並列性を保つため最小限に）
                sleep 1
            else
                log_error "Worker $((i+1)) 起動失敗（最大リトライ回数超過）"
            fi
        else
            log_error "必要なスクリプトが見つかりません: agent_manager.sh または auth_helper.sh"
        fi
    done
    
    log_info "全Workerの起動処理完了"
    
    # ステータスを更新
    jq '.status = "workers_started"' "$session_file" > "${session_file}.tmp" && mv "${session_file}.tmp" "$session_file"
    
    # セッションIDを返す
    echo "$session_id"
    
    log_success "並列実装セッション開始: $session_id"
    return 0
}

# Worker完了を監視
monitor_worker_completion() {
    local session_id="$1"
    local session_file="${PARALLEL_SESSION_DIR}/${session_id}.json"
    
    if [ ! -f "$session_file" ]; then
        log_error "セッションファイルが見つかりません: $session_id"
        return 1
    fi
    
    # セッション情報を読み込み
    local worker_panes=($(jq -r '.worker_panes[]' "$session_file"))
    local completed_workers=()
    
    log_info "Worker完了を監視中..."
    
    # 各Workerの状態をチェック
    for pane in "${worker_panes[@]}"; do
        local screen_content=$(tmux capture-pane -t "${MULTIAGENT_SESSION}:0.$pane" -p)
        
        # 完了判定（"実装完了"というキーワードを探す）
        if echo "$screen_content" | grep -q "実装完了"; then
            completed_workers+=("$pane")
            log_info "Worker (ペイン $pane) 完了検出"
        fi
    done
    
    # 完了率を計算
    local completion_rate=$((${#completed_workers[@]} * 100 / ${#worker_panes[@]}))
    
    # ステータスを更新
    # completed_workersの配列を安全に生成
    local completed_workers_json=""
    if [ ${#completed_workers[@]} -gt 0 ]; then
        completed_workers_json=$(printf '%s,' "${completed_workers[@]}" | sed 's/,$//')
    fi
    
    jq --argjson completed "[$completed_workers_json]" \
       --arg rate "$completion_rate" \
       '.completed_workers = $completed | .completion_rate = $rate' \
       "$session_file" > "${session_file}.tmp" && mv "${session_file}.tmp" "$session_file"
    
    echo "$completion_rate"
}


# 並列実装ステータスを取得
get_parallel_status() {
    local session_id="$1"
    
    if [ -z "$session_id" ]; then
        # 全セッションをリスト
        ls -1 "$PARALLEL_SESSION_DIR"/*.json 2>/dev/null | while read session_file; do
            local sid=$(basename "$session_file" .json)
            local status=$(jq -r '.status' "$session_file")
            local timestamp=$(jq -r '.timestamp' "$session_file")
            local completion=$(jq -r '.completion_rate // 0' "$session_file")
            
            echo "$sid | Status: $status | Completion: ${completion}% | Time: $timestamp"
        done
    else
        # 特定セッションの詳細
        local session_file="${PARALLEL_SESSION_DIR}/${session_id}.json"
        
        if [ -f "$session_file" ]; then
            jq . "$session_file"
        else
            echo "Session not found: $session_id"
            return 1
        fi
    fi
}

# メイン処理
main() {
    local command="${1:-}"
    shift || true
    
    case "$command" in
        "start")
            start_parallel_implementation "$@"
            ;;
        "monitor")
            monitor_worker_completion "$@"
            ;;
        "status")
            get_parallel_status "$@"
            ;;
        *)
            echo "使用法: $0 {start|monitor|trigger-boss|status} [options]"
            echo ""
            echo "コマンド:"
            echo "  start <prompt> [worker_count] [complexity] [auto_merge]"
            echo "  monitor <session_id>"
            echo "  status [session_id]"
            exit 1
            ;;
    esac
}

# 実行
main "$@"