#!/bin/bash
# =============================================================================
# watcher_service.sh v3
# Stock_Bot ONLY -- reads/writes Stock_Bot/ subdirectory exclusively.
#
# KEY DESIGN CHANGES FROM v2:
#   - NEVER does git commit or git push (was deleting WhatsApp/ and other dirs)
#   - Reads commands via: git show origin/main:Stock_Bot/commands/cmd.json
#   - Pushes results via: GitHub REST API (curl) to Stock_Bot/feedback/result.json
#   - Code updates via: git fetch + git show + cp (never touches git index)
#   - Has zero effect on any directory outside Stock_Bot/
# =============================================================================

PAT="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"
REPO="Jake-Culberson/Claud-Code"
API="https://api.github.com/repos/$REPO/contents"
DIR="/home/opc/trading"

cd "$DIR" || exit 1
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Watcher v3 started (Stock_Bot only, API result push)"

LAST_KEEPALIVE=0
LAST_CMD_ID=""

# ── Helper: push a file to GitHub via REST API ────────────────────────────
api_push() {
    local path="$1"    # e.g. Stock_Bot/feedback/result.json
    local file="$2"    # local file to upload
    local msg="$3"     # commit message

    # Get current SHA of remote file (needed for update)
    SHA=$(curl -s -H "Authorization: Bearer $PAT" \
        "$API/$path" | python3 -c "
import sys,json
d=json.load(sys.stdin)
print(d.get('sha',''))
" 2>/dev/null)

    # Base64 encode content and push
    B64=$(base64 -w0 "$file")
    python3 -c "
import json, sys
d = {'message': sys.argv[1], 'content': sys.argv[2]}
if sys.argv[3]: d['sha'] = sys.argv[3]
print(json.dumps(d))
" "$msg" "$B64" "$SHA" > /tmp/_api_payload.json

    RESULT=$(curl -s -X PUT \
        -H "Authorization: Bearer $PAT" \
        -H "Content-Type: application/json" \
        -d @/tmp/_api_payload.json \
        "$API/$path")

    echo "$RESULT" | python3 -c "
import sys,json
d=json.load(sys.stdin)
if 'commit' in d:
    print('OK: ' + d['commit']['sha'][:10])
else:
    print('FAIL: ' + str(d.get('message',''))[:80], file=sys.stderr)
    sys.exit(1)
" 2>&1
}

while true; do
    # ── Clean stale git locks ────────────────────────────────────────────
    for lock in .git/index.lock .git/MERGE_HEAD; do
        [ -f "$lock" ] && rm -f "$lock"
    done

    # ── Fetch remote (read-only, never commits) ──────────────────────────
    git fetch origin main -q 2>/dev/null

    LOCAL=$(git rev-parse HEAD 2>/dev/null)
    REMOTE=$(git rev-parse origin/main 2>/dev/null)

    if [ "$LOCAL" != "$REMOTE" ]; then
        echo "[$(date '+%Y-%m-%d %H:%M:%S')] New commits -- syncing Stock_Bot/ code files..."

        # Read files directly from remote ref -- no index manipulation
        git show origin/main:Stock_Bot/StockTrading.py > "$DIR/StockTrading.py" 2>/dev/null && \
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] StockTrading.py updated"

        git show origin/main:Stock_Bot/watcher_helper.py > "$DIR/watcher_helper.py" 2>/dev/null

        # Advance local HEAD to remote so next loop sees no diff
        # Use FETCH_HEAD merge (fast-forward only) -- preserves all remote files
        git merge --ff-only origin/main -q 2>/dev/null || \
            git reset --hard origin/main -q 2>/dev/null

        # Recreate runtime dirs in case git touched them
        mkdir -p "$DIR/features/daily" "$DIR/features/weekly"
        mkdir -p "$DIR/data/db" "$DIR/logs" "$DIR/models"
        mkdir -p "$DIR/charts" "$DIR/backup"

        # Remove non-trading dirs from VM working dir (not from repo)
        for BLACKLISTED in "CCRE-Work-Claude" "study-guides" "Crossflow" "Progress Reports" "WhatsApp" "_archive"; do
            [ -d "$DIR/$BLACKLISTED" ] && rm -rf "$DIR/$BLACKLISTED" && \
                echo "[$(date '+%Y-%m-%d %H:%M:%S')] Removed local copy: $BLACKLISTED"
        done

        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Code updated -- bot left running (no auto-restart)"

        # ── Read and execute pending command ─────────────────────────────
        CMD_JSON=$(git show origin/main:Stock_Bot/commands/cmd.json 2>/dev/null)
        if [ -n "$CMD_JSON" ]; then
            EXECUTED=$(echo "$CMD_JSON" | python3 -c "
import sys,json
d=json.loads(sys.stdin.read())
print(str(d.get('executed',False)).lower())
" 2>/dev/null)
            CMD_ID=$(echo "$CMD_JSON" | python3 -c "
import sys,json
d=json.loads(sys.stdin.read())
print(d.get('id','unknown'))
" 2>/dev/null)

            if [ "$EXECUTED" != "true" ] && [ "$CMD_ID" != "$LAST_CMD_ID" ]; then
                LAST_CMD_ID="$CMD_ID"
                echo "[$(date '+%Y-%m-%d %H:%M:%S')] Executing: $CMD_ID"

                # Write payload to temp script
                echo "$CMD_JSON" | python3 -c "
import sys,json
d=json.loads(sys.stdin.read())
open('/tmp/cmd_payload.sh','w').write(d.get('payload','echo no_payload'))
" 2>/dev/null

                # Run command
                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"

                # Build result JSON
                python3 -c "
import json, sys, datetime
output = open('/tmp/cmd_output.txt').read()
result = {
    'cmd_id': sys.argv[1],
    'executed_at': datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'),
    'exit_code': int(sys.argv[2]),
    'output': output
}
open('/tmp/result.json','w').write(json.dumps(result, indent=2))
" "$CMD_ID" "$EXIT_CODE"

                # Push result via API -- ONLY touches Stock_Bot/feedback/result.json
                PUSH_RESULT=$(api_push \
                    "Stock_Bot/feedback/result.json" \
                    "/tmp/result.json" \
                    "vm: result for $CMD_ID at $(date '+%Y-%m-%d %H:%M')")

                if echo "$PUSH_RESULT" | grep -q "^OK"; then
                    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Results pushed ($PUSH_RESULT)"
                else
                    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Push failed: $PUSH_RESULT"
                fi
            fi
        fi
    fi

    # ── KEEPALIVE: hourly check ──────────────────────────────────────────
    NOW=$(date +%s)
    if [ $((NOW - LAST_KEEPALIVE)) -ge 3600 ]; then
        LAST_KEEPALIVE=$NOW
        if ! pgrep -f "python3.11.*StockTrading" > /dev/null 2>&1; then
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] KEEPALIVE: bot not running -- restarting"
            source "$DIR/venv/bin/activate"
            nohup python3.11 "$DIR/StockTrading.py" --mode both --max-workers 8 \
                > "$DIR/trading.log" 2>&1 &
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] KEEPALIVE: bot restarted -- PID $!"
        else
            echo "[$(date '+%Y-%m-%d %H:%M:%S')] KEEPALIVE: bot running OK"
        fi
    fi

    sleep 30
done
