#!/bin/bash
# =============================================================================
# github_watcher.sh -- Claude <-> Oracle VM command bridge (permanent fix)
# =============================================================================
# Cron entry: */2 * * * * /home/opc/trading/github_watcher.sh
#
# HOW IT WORKS:
#   1. Cleans any stale git locks from interrupted previous runs
#   2. Pulls new commits from GitHub
#   3. If StockTrading.py changed, restarts the bot (market-hours aware)
#   4. Executes any pending command from commands/cmd.json
#   5. Pushes results back to GitHub feedback/
#
# IMPORTANT: Command payloads must NEVER contain git operations (fetch, pull,
# reset, commit, push). Git is managed exclusively by this script. Mixing git
# calls in payloads is what caused repeated stuck-watcher issues.
# =============================================================================

DIR="/home/opc/trading"
LOG="$DIR/watcher.log"
TOKEN="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"

cd "$DIR" || exit 1

# ── Step 1: Clean any stale git locks from interrupted previous runs ──────────
# These are left behind when a previous watcher run was killed mid-git-operation.
# Without this cleanup the next git fetch/pull hangs forever.
for lock_file in .git/index.lock .git/MERGE_HEAD .git/CHERRY_PICK_HEAD .git/REBASE_MERGE; do
    if [ -f "$lock_file" ]; then
        rm -f "$lock_file"
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Cleaned stale git lock: $lock_file" >> "$LOG"
    fi
done

# ── Step 2: Pull latest from GitHub ──────────────────────────────────────────
git fetch origin main -q 2>>"$LOG"
LOCAL=$(git rev-parse HEAD 2>/dev/null)
REMOTE=$(git rev-parse origin/main 2>/dev/null)

if [ "$LOCAL" = "$REMOTE" ]; then
    exit 0  # Nothing new
fi

echo "[$(date '+%Y-%m-%d %H:%M:%S')] New commits detected — pulling..." >> "$LOG"

# Force-sync to GitHub (local changes never win — GitHub is the source of truth)
git reset --hard origin/main -q 2>>"$LOG"

# ── Step 3: Handle StockTrading.py update ────────────────────────────────────
if git diff HEAD~1 HEAD --name-only 2>/dev/null | grep -q "StockTrading.py"; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] StockTrading.py updated" >> "$LOG"
    HOUR=$(TZ="America/New_York" date +%H)
    if [ "$HOUR" -ge 16 ] || [ "$HOUR" -lt 9 ]; then
        pkill -f "python3.11.*StockTrading" 2>/dev/null || true
        sleep 3
        source "$DIR/venv/bin/activate"
        nohup python3.11 "$DIR/StockTrading.py" > "$DIR/trading.log" 2>&1 &
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Bot restarted (script update) — PID $!" >> "$LOG"
    else
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Market open — restart queued for 4:05 PM ET" >> "$LOG"
        echo "pkill -f 'python3.11.*StockTrading' 2>/dev/null; sleep 3; cd /home/opc/trading && source venv/bin/activate && nohup python3.11 StockTrading.py > trading.log 2>&1 &" | at 16:05 2>/dev/null || true
    fi
fi

# ── Step 4: Execute pending command ──────────────────────────────────────────
CMD_FILE="$DIR/commands/cmd.json"
if [ ! -f "$CMD_FILE" ]; then
    exit 0
fi

# Python reads cmd.json safely and writes payload to a temp file.
# This avoids ALL shell quoting/newline issues with multiline payloads.
python3 - << 'PYEOF'
import json, sys
try:
    d = json.load(open('/home/opc/trading/commands/cmd.json'))
    executed = str(d.get('executed', False)).lower()
    cmd_id   = d.get('id', 'unknown')
    if executed != 'true':
        with open('/tmp/cmd_payload.sh', 'w') as f:
            f.write(d.get('payload', 'echo no_payload'))
    sys.stdout.write(f"{executed}|{cmd_id}\n")
except Exception as e:
    sys.stdout.write(f"true|error:{e}\n")
PYEOF

CMD_INFO=$(python3 -c "
import json, sys
try:
    d = json.load(open('/home/opc/trading/commands/cmd.json'))
    print(str(d.get('executed', False)).lower() + '|' + d.get('id', 'unknown'))
except:
    print('true|read_error')
")

EXECUTED=$(echo "$CMD_INFO" | cut -d'|' -f1)
CMD_ID=$(echo "$CMD_INFO" | cut -d'|' -f2)

if [ "$EXECUTED" = "true" ]; then
    exit 0
fi

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Executing: $CMD_ID" >> "$LOG"

# Run payload from temp file — safe for multiline, special chars, etc.
bash /tmp/cmd_payload.sh > /tmp/cmd_output.txt 2>&1
EXIT_CODE=$?

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Exit code: $EXIT_CODE" >> "$LOG"

# ── Step 5: Build feedback and push to GitHub ─────────────────────────────────
mkdir -p "$DIR/feedback"
python3 /home/opc/trading/watcher_helper.py "$CMD_ID" "$EXIT_CODE"

# Mark command as executed
python3 -c "
import json
d = json.load(open('/home/opc/trading/commands/cmd.json'))
d['executed'] = True
json.dump(d, open('/home/opc/trading/commands/cmd.json', 'w'), indent=2)
"

git config user.email "vm@oracle-trading-bot" 2>/dev/null
git config user.name "Oracle VM" 2>/dev/null
git add feedback/result.json feedback/snapshot.json commands/cmd.json
git commit -m "vm: result for $CMD_ID at $(date '+%Y-%m-%d %H:%M')" -q 2>>"$LOG"
git push origin main -q 2>>"$LOG"

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Results pushed" >> "$LOG"
