#!/bin/bash
# WW.sh - Chrome画面キャプチャスクリプト（ステータス機能なし版）
# ステータス確認は status.sh を使用してください

# --- 設定項目 ---
TARGET_URL="https://https://www.google.com/"
LOGICAL_WIDTH=320
LOGICAL_HEIGHT=480
OUTPUT_WIDTH=480
OUTPUT_HEIGHT=320

DISPLAY_NUM=":99"
FPS=2
PIX_FMT="rgb565be"
OUTPUT_FILE="../Canby/XV1900CU.bin"
PNG_FILE="../Canby/XV1900CU.png"
TMP_FILE="${OUTPUT_FILE}.tmp"
CHROME_PROFILE="/tmp/chrome-profile-web2bin"
CHROME_PID_FILE="/tmp/chrome_web2bin.pid"
MAIN_PID_FILE="/tmp/WW_main.pid"
LOCK_FILE="/tmp/WW.lock"
LOG_FILE="/var/log/WW.log"
CONFIG_FILE="ww_config"  # 設定ファイルのパス

# 計算
EXPECTED_SIZE=$((OUTPUT_WIDTH * OUTPUT_HEIGHT * 2))  # rgb565: 2バイト/ピクセル

# --- 関数定義 ---

# 設定ファイルを読み込む関数
read_config() {
    # デフォルト値
    OFF_START_HOUR=23
    OFF_END_HOUR=8
    OFF_FILE_SIZE=50
    
    if [ -f "$CONFIG_FILE" ]; then
        # 設定ファイルを読み込む前に、コメントと空行を除去して安全に処理
        source <(grep -v '^#' "$CONFIG_FILE" | grep -v '^$')
    else
        log_message "警告: 設定ファイル $CONFIG_FILE が見つかりません。デフォルト値を使用します。"
    fi
    
    # 変数が設定されていることを確認
    : "${OFF_START_HOUR:=23}"
    : "${OFF_END_HOUR:=8}"
    : "${OFF_FILE_SIZE:=50}"
    
    # デバッグ用（ログ出力は別の関数で行う）
    echo "$OFF_START_HOUR $OFF_END_HOUR $OFF_FILE_SIZE"
}

# 夜間モードかを判定する関数
is_night_mode() {
    local current_hour=$(date +%H)
    
    # 時間を数値に変換（先頭の0を削除）
    current_hour=$((10#$current_hour))
    OFF_START_HOUR=$((10#$OFF_START_HOUR))
    OFF_END_HOUR=$((10#$OFF_END_HOUR))
    
    if [ "$OFF_START_HOUR" -lt "$OFF_END_HOUR" ]; then
        # 開始時間 < 終了時間（例: 1時から8時まで）
        if [ "$current_hour" -ge "$OFF_START_HOUR" ] && [ "$current_hour" -lt "$OFF_END_HOUR" ]; then
            return 0  # 夜間モード
        else
            return 1  # 通常モード
        fi
    else
        # 開始時間 > 終了時間（例: 23時から8時まで）- 日を跨ぐ場合
        if [ "$current_hour" -ge "$OFF_START_HOUR" ] || [ "$current_hour" -lt "$OFF_END_HOUR" ]; then
            return 0  # 夜間モード
        else
            return 1  # 通常モード
        fi
    fi
}

# ログ記録
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" > /dev/null 2>&1
}

# すべてのプロセスを停止
stop_all() {
    log_message "停止中... プロセスを掃除します。"

    # メインプロセスの停止
    if [ -f "$MAIN_PID_FILE" ]; then
        MAIN_PID=$(cat "$MAIN_PID_FILE")
        if kill -0 "$MAIN_PID" 2>/dev/null; then
            kill -TERM "$MAIN_PID" 2>/dev/null
            sleep 2
            kill -9 "$MAIN_PID" 2>/dev/null > /dev/null 2>&1
            log_message "メインプロセスを停止しました (PID: $MAIN_PID)"
        fi
        rm -f "$MAIN_PID_FILE"
    fi

    # Chromeプロセスの停止（プロファイルベースで検索）
    pkill -9 -f "chrome.*$CHROME_PROFILE" 2>/dev/null
    log_message "Chromeプロセスを停止しました"

    # その他のプロセス停止
    pkill -9 -f "Xvfb $DISPLAY_NUM" 2>/dev/null
    pkill -9 -f "ffmpeg.*DISPLAY=$DISPLAY_NUM" 2>/dev/null
    pkill -9 -f "WW.sh.*--daemon" 2>/dev/null

    # ファイル掃除
    rm -rf "$CHROME_PROFILE" 2>/dev/null
    rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null
    rm -f "$LOCK_FILE" 2>/dev/null
    rm -f "$TMP_FILE" 2>/dev/null
    rm -f "$CHROME_PID_FILE" 2>/dev/null

    log_message "すべてのプロセスを停止しました。"
    echo "WW.sh を停止しました。"
}

# スクリプトの使用方法を表示
show_usage() {
    echo "使用方法: $0 [オプション]"
    echo "オプション:"
    echo "  -start     デーモンとして起動（ログアウト後も継続）"
    echo "  -stop      実行中のデーモンを停止"
    echo "  -png       単一PNGスナップショットを作成"
    echo "  -log       ログファイルを表示"
    echo "  -help      このヘルプを表示"
    echo ""
    echo "ステータス確認: ./status.sh を使用してください"
    echo "引数を指定しない場合は、対話型で起動します。"
}

# ログ表示
show_log() {
    if [ -f "$LOG_FILE" ]; then
        echo "=== WW.sh ログファイル (最新20行) ==="
        tail -20 "$LOG_FILE"
    else
        echo "ログファイルが存在しません: $LOG_FILE"
    fi
}

# PNGスナップショット作成
create_png() {
    echo "PNGスナップショットを作成します..."

    # 一時的なXvfb起動
    Xvfb $DISPLAY_NUM -screen 0 ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT}x24+32 -ac -nolisten tcp &
    XVFB_PID=$!
    sleep 3

    # Chrome起動（一時的）
    export DISPLAY=$DISPLAY_NUM
    export GNOME_KEYRING_CONTROL=""
    export GNOME_KEYRING_PID=""

    google-chrome \
      --user-data-dir="/tmp/chrome-snapshot" \
      --password-store=basic \
      --no-first-run \
      --no-default-browser-check \
      --app="$TARGET_URL" \
      --window-size=$LOGICAL_WIDTH,$LOGICAL_HEIGHT \
      --window-position=0,0 \
      --disable-infobars \
      --hide-scrollbars \
      --disable-gpu \
      --disable-software-rasterizer \
      --no-sandbox \
      --disable-dev-shm-usage \
      --silent-launch \
      --test-type > /dev/null 2>&1 &

    CHROME_PID=$!
    sleep 5

    # PNGキャプチャ
    echo "キャプチャ中..."
    ffmpeg -loglevel quiet -f x11grab -draw_mouse 0 -video_size ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT} -i ${DISPLAY_NUM}.0 \
        -vframes 1 -vf "transpose=1" -y "$PNG_FILE"

    # 後処理
    kill -9 "$CHROME_PID" 2>/dev/null
    kill -9 "$XVFB_PID" 2>/dev/null
    pkill -f "Xvfb $DISPLAY_NUM" 2>/dev/null
    rm -rf "/tmp/chrome-snapshot" 2>/dev/null
    rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null

    if [ -f "$PNG_FILE" ]; then
        echo "完了: $PNG_FILE"
    else
        echo "エラー: PNGファイルの作成に失敗しました"
        exit 1
    fi
}

# 完全なデーモン化関数
daemonize() {
    # 既存のファイルディスクリプタを閉じる
    exec 0</dev/null
    exec 1>/dev/null
    exec 2>/dev/null

    # 新しいセッションを作成（完全に親プロセスから分離）
    setsid "$0" --real-daemon "$@" &
    exit 0
}

# 実際のデーモン処理（完全に分離された環境で実行）
run_real_daemon() {
    log_message "=== WW.sh デーモン起動 ==="
    
    # 起動時に設定ファイルを読み込んでログ出力
    read_config
    log_message "設定ファイルを読み込みました:"
    log_message "  OFF_START_HOUR=$OFF_START_HOUR (表示オフ開始時間)"
    log_message "  OFF_END_HOUR=$OFF_END_HOUR (表示オフ終了時間)"
    log_message "  OFF_FILE_SIZE=$OFF_FILE_SIZE (オフ時のファイルサイズ)"
    log_message "  期待サイズ: $EXPECTED_SIZE バイト (通常モード時)"

    # 自身のPIDを保存
    echo $$ > "$MAIN_PID_FILE"
    log_message "メインプロセスPID: $$"

    # ロックファイルを作成
    touch "$LOCK_FILE"

    # 終了時の処理を設定
    trap 'log_message "終了シグナルを受信しました。掃除します..."; stop_all; exit 0' SIGINT SIGTERM EXIT

    # ログディレクトリ作成
    mkdir -p "$(dirname "$LOG_FILE")"

    # 掃除と準備
    log_message "1. 既存プロセスを掃除中..."
    pkill -9 -f "Xvfb $DISPLAY_NUM" 2>/dev/null
    pkill -9 -f "chrome.*$CHROME_PROFILE" 2>/dev/null
    pkill -9 -f "ffmpeg.*DISPLAY=$DISPLAY_NUM" 2>/dev/null
    rm -rf "$CHROME_PROFILE" 2>/dev/null
    rm -f /tmp/.X${DISPLAY_NUM:1}-lock 2>/dev/null
    sleep 3

    # 1. 仮想画面の作成
    log_message "2. Xvfbを起動中..."
    nohup Xvfb $DISPLAY_NUM -screen 0 ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT}x24+32 -ac -nolisten tcp > /dev/null 2>&1 &
    sleep 5

    # Xvfbの起動確認
    if ! pgrep -f "Xvfb $DISPLAY_NUM" > /dev/null; then
        log_message "エラー: Xvfbの起動に失敗しました"
        stop_all
        exit 1
    fi
    log_message "Xvfb起動完了"

    # 2. ブラウザ起動
    log_message "3. Chromeを起動中..."
    export DISPLAY=$DISPLAY_NUM
    export GNOME_KEYRING_CONTROL=""
    export GNOME_KEYRING_PID=""

    # Chrome起動（簡易オプションで）
    nohup google-chrome \
      --user-data-dir="$CHROME_PROFILE" \
      --app="$TARGET_URL" \
      --window-size=$LOGICAL_WIDTH,$LOGICAL_HEIGHT \
      --no-first-run \
      --disable-infobars \
      --hide-scrollbars \
      --no-sandbox \
      --disable-gpu \
      --disable-software-rasterizer \
      --silent-launch \
      --test-type > /dev/null 2>&1 &

    CHROME_PID=$!
    # PIDファイルは作成するが、プロセスが変わっても問題ないようにする
    echo $CHROME_PID > "$CHROME_PID_FILE"
    log_message "Chrome起動完了。初期PID: $CHROME_PID"

    # Chromeの起動を確実にする
    sleep 10

    # Chromeプロセスの生存確認（プロファイルベースで）
    CHROME_COUNT=$(pgrep -f "chrome.*$CHROME_PROFILE" | wc -l)
    if [ "$CHROME_COUNT" -eq 0 ]; then
        log_message "エラー: Chromeの起動に失敗しました"
        stop_all
        exit 1
    fi

    log_message "4. キャプチャ設定"
    log_message "  フォーマット: $PIX_FMT"
    log_message "  期待サイズ: $EXPECTED_SIZE バイト"
    log_message "  ループ間隔: 0.9秒"
    log_message "連続キャプチャ開始"

    # メインキャプチャループ
    FRAME_COUNT=0
    START_TIME=$(date +%s)
    LAST_LOG_TIME=$START_TIME
    LAST_NIGHT_MODE_CHECK=$START_TIME
    NIGHT_MODE=false

    while true; do
        FRAME_COUNT=$((FRAME_COUNT + 1))
        CURRENT_TIME=$(date +%s)
        
        # 設定ファイルを毎回読み込む（5秒ごと）
        if [ $((CURRENT_TIME - LAST_NIGHT_MODE_CHECK)) -ge 5 ]; then
            read_config
            if is_night_mode; then
                if [ "$NIGHT_MODE" = false ]; then
                    log_message "夜間モードに切り替わりました"
                    NIGHT_MODE=true
                fi
            else
                if [ "$NIGHT_MODE" = true ]; then
                    log_message "通常モードに切り替わりました"
                    NIGHT_MODE=false
                fi
            fi
            LAST_NIGHT_MODE_CHECK=$CURRENT_TIME
        fi

        # 夜間モードの処理
        if [ "$NIGHT_MODE" = true ]; then
            # 夜間モード時は小さなダミーファイルを生成
            dd if=/dev/zero of="$OUTPUT_FILE" bs=1 count="$OFF_FILE_SIZE" 2>/dev/null
            # 待機時間を調整
            sleep 0.9
            continue
        fi

        # 通常モードのキャプチャ処理
        # 一時ファイル名
        TEMP_FILE="/tmp/frame_$$_${FRAME_COUNT}.bin"

        # 単一フレームをキャプチャ
        ffmpeg -loglevel error -f x11grab -draw_mouse 0 \
            -video_size ${LOGICAL_WIDTH}x${LOGICAL_HEIGHT} \
            -i ${DISPLAY_NUM}.0 \
            -vf "transpose=1,format=rgb24" \
            -sws_flags neighbor \
            -pix_fmt rgb565be \
            -vcodec rawvideo \
            -f rawvideo \
            -frames 1 \
            -y "$TEMP_FILE" 2>&1

        if [ -f "$TEMP_FILE" ]; then
            ACTUAL_SIZE=$(stat -c%s "$TEMP_FILE" 2>/dev/null || echo 0)

            if [ "$ACTUAL_SIZE" -eq "$EXPECTED_SIZE" ]; then
                # 正しいサイズの場合、アトミックに上書き
                mv -f "$TEMP_FILE" "$OUTPUT_FILE"

                # 定期的なログ出力（2分ごと）
                if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 120 ]; then
                    ELAPSED=$((CURRENT_TIME - START_TIME))
                    if [ $ELAPSED -gt 0 ]; then
                        ACTUAL_FPS=$(echo "scale=1; $FRAME_COUNT / $ELAPSED" | bc -l)
                        log_message "動作中: $FRAME_COUNT フレーム処理 (平均FPS: $ACTUAL_FPS)"

                        # プロセス状態もログに記録
                        CHROME_COUNT=$(pgrep -f "chrome.*$CHROME_PROFILE" | wc -l)
                        FFMPEG_COUNT=$(pgrep -f "ffmpeg.*x11grab.*:99" | wc -l)
                        log_message "  プロセス状態: Chrome($CHROME_COUNT), FFmpeg($FFMPEG_COUNT)"
                        LAST_LOG_TIME=$CURRENT_TIME
                    fi
                fi
            else
                # サイズが異なる場合
                if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 300 ]; then  # 5分ごと
                    log_message "警告: フレームサイズ異常 ($ACTUAL_SIZEバイト, 期待: $EXPECTED_SIZEバイト)"
                    LAST_LOG_TIME=$CURRENT_TIME
                fi

                # それでも最初の1フレーム分を抽出
                if [ "$ACTUAL_SIZE" -ge "$EXPECTED_SIZE" ]; then
                    dd if="$TEMP_FILE" of="$OUTPUT_FILE" bs=$EXPECTED_SIZE count=1 2>/dev/null
                fi
                rm -f "$TEMP_FILE"
            fi
        else
            if [ $((CURRENT_TIME - LAST_LOG_TIME)) -ge 300 ]; then  # 5分ごと
                log_message "警告: フレームキャプチャ失敗"
                LAST_LOG_TIME=$CURRENT_TIME
            fi
        fi

        # 指定した間隔で待機（0.9秒）
        sleep 0.9
    done
}

# --- メイン処理 ---

case "$1" in
    -start|--start|start)
        # 既に実行中かチェック
        if [ -f "$LOCK_FILE" ] && [ -f "$MAIN_PID_FILE" ]; then
            PID=$(cat "$MAIN_PID_FILE")
            if kill -0 "$PID" 2>/dev/null; then
                echo "WW.sh は既に実行中です (PID: $PID)"
                echo "停止するには: $0 -stop"
                echo "状態確認: ./status.sh"
                exit 1
            else
                # プロセスは死んでいるがロックファイルが残っている場合
                rm -f "$LOCK_FILE" "$MAIN_PID_FILE"
            fi
        fi

        # 完全にデーモン化して起動
        echo "WW.sh をデーモンとして起動します..."
        echo "ログファイル: $LOG_FILE"
        echo "出力ファイル: $OUTPUT_FILE"
        echo ""
        echo "ログアウトしても動作を継続します。"
        echo "停止するには: $0 -stop"
        echo "状態確認: ./status.sh"

        # デーモン化して起動
        daemonize

        # 少し待ってからステータスを表示
        sleep 3
        echo "起動処理を開始しました。"
        echo "詳細はログファイルを確認してください:"
        echo "tail -f $LOG_FILE"
        ;;

    --real-daemon)
        # 実際のデーモンプロセス（完全に分離された環境）
        run_real_daemon
        ;;

    -stop|--stop|stop)
        if [ ! -f "$LOCK_FILE" ] && [ ! -f "$MAIN_PID_FILE" ]; then
            echo "WW.sh は実行中ではありません。"
            exit 1
        fi

        echo "WW.sh を停止します..."
        stop_all
        ;;

    -png|--png|png)
        create_png
        ;;

    -log|--log|log)
        show_log
        ;;

    -help|--help|help)
        show_usage
        ;;

    *)
        # 引数がない場合は対話型メニュー
        if [ $# -eq 0 ]; then
            echo "=== WW.sh 画面キャプチャスクリプト ==="
            echo "ステータス確認: ./status.sh を使用してください"
            echo ""
            echo "現在の状態（簡易表示）:"
            if [ -f "$LOCK_FILE" ]; then
                echo "- システム: 実行中（ロックファイルあり）"
            else
                echo "- システム: 停止中"
            fi

            if [ -f "$OUTPUT_FILE" ]; then
                FILE_AGE=$(($(date +%s) - $(stat -c %Y "$OUTPUT_FILE" 2>/dev/null || echo 0)))
                if [ "$FILE_AGE" -lt 10 ]; then
                    echo "- 出力ファイル: 最新 ($FILE_AGE秒前)"
                else
                    echo "- 出力ファイル: 更新あり ($FILE_AGE秒前)"
                fi
            fi
            
            # 設定ファイルの内容を表示
            if [ -f "$CONFIG_FILE" ]; then
                echo "- 設定ファイル: 存在します"
                source <(grep -v '^#' "$CONFIG_FILE" | grep -v '^$')
                echo "  夜間モード時間帯: ${OFF_START_HOUR:-23}時〜${OFF_END_HOUR:-8}時"
                echo "  夜間モード時ファイルサイズ: ${OFF_FILE_SIZE:-50}バイト"
            else
                echo "- 設定ファイル: 存在しません（デフォルト値を使用）"
                echo "  夜間モード時間帯: 23時〜8時"
                echo "  夜間モード時ファイルサイズ: 50バイト"
            fi
            
            echo ""
            echo "操作を選択してください:"
            echo "1) 起動 (-start)"
            echo "2) 停止 (-stop)"
            echo "3) PNGスナップショット (-png)"
            echo "4) ログ表示 (-log)"
            echo "5) 状態確認 (./status.sh を実行)"
            echo "6) ヘルプ (-help)"
            echo "7) 終了"
            echo ""
            read -p "選択 [1-7]: " choice

            case $choice in
                1)
                    bash "$0" -start
                    ;;
                2)
                    bash "$0" -stop
                    ;;
                3)
                    bash "$0" -png
                    ;;
                4)
                    bash "$0" -log
                    ;;
                5)
                    echo "状態確認は ./status.sh を実行してください"
                    if [ -f "./status.sh" ]; then
                        read -p "今すぐ実行しますか？ (y/N): " exec_status
                        if [[ "$exec_status" =~ ^[Yy]$ ]]; then
                            ./status.sh
                        fi
                    else
                        echo "status.sh が見つかりません。作成してください。"
                    fi
                    ;;
                6)
                    bash "$0" -help
                    ;;
                7)
                    exit 0
                    ;;
                *)
                    echo "無効な選択です。"
                    exit 1
                    ;;
            esac
        else
            echo "不明なオプション: $1"
            show_usage
            exit 1
        fi
        ;;
esac

exit

