#!/usr/bin/env python3
import json
from pathlib import Path
from datetime import datetime

ROOT = Path('/Users/openclaw/.openclaw/workspace')
TMP = ROOT / 'tmp'
TMP.mkdir(parents=True, exist_ok=True)

FEED = ROOT / 'knowledge/projects/dashboard-feed.json'
PENDING_MD = ROOT / 'knowledge/rules/pending-promotions.md'
GIT_STATE = ROOT / 'tmp/job-state/git-push.state'
DAILY = ROOT / f"knowledge/daily/{datetime.now().strftime('%Y-%m-%d')}.md"
OUT = ROOT / 'tmp/dashboard-data.json'
OUT_ROOT = ROOT / 'dashboard-data.json'
BEE_SYNC_LAST = ROOT / 'tmp/bee-sync-last-run.txt'


def read_json(path, default):
    try:
        return json.loads(path.read_text(encoding='utf-8'))
    except Exception:
        return default


def parse_pending_count():
    if not PENDING_MD.exists():
        return 0, []
    items = []
    in_auto = False
    for ln in PENDING_MD.read_text(encoding='utf-8', errors='ignore').splitlines():
        s = ln.strip()
        if s == '<!-- AUTO_PENDING_PROMOTIONS_START -->':
            in_auto = True
            continue
        if s == '<!-- AUTO_PENDING_PROMOTIONS_END -->':
            in_auto = False
            continue
        if in_auto and s.startswith('- [ ] '):
            items.append(s[6:])
    return len(items), items[:8]


def parse_git_state():
    state = {'FAIL_COUNT': '0', 'ALERT_SENT': '0'}
    if GIT_STATE.exists():
        for ln in GIT_STATE.read_text(encoding='utf-8', errors='ignore').splitlines():
            if '=' in ln:
                k, v = ln.split('=', 1)
                state[k.strip()] = v.strip().strip('"')
    fail = int(state.get('FAIL_COUNT', '0') or 0)
    return {
        'ok': fail == 0,
        'label': 'Git Push OK' if fail == 0 else f'Git Push Alert ({fail})',
        'severity': 'ok' if fail == 0 else 'bad'
    }


def parse_critical_facts():
    if not DAILY.exists():
        return {'ok': False, 'label': 'Critical Facts Unknown', 'severity': 'warn'}
    txt = DAILY.read_text(encoding='utf-8', errors='ignore')
    if 'Summary: 3/3 passed' in txt or 'Summary: 4/4 passed' in txt:
        return {'ok': True, 'label': 'Memory Checks OK', 'severity': 'ok'}
    if 'Critical Facts Retrieval Check (auto)' in txt:
        return {'ok': False, 'label': 'Memory Checks Degraded', 'severity': 'warn'}
    return {'ok': False, 'label': 'Memory Checks Missing', 'severity': 'warn'}


def parse_bee_sync_last_run():
    if not BEE_SYNC_LAST.exists():
        return {'ok': False, 'label': 'Bee Sync: Never', 'severity': 'warn'}
    ts = BEE_SYNC_LAST.read_text(encoding='utf-8', errors='ignore').strip()
    return {'ok': True, 'label': f'Bee Sync Last Run: {ts}', 'severity': 'ok'}


feed = read_json(FEED, {
    'activeWork': [], 'blocked': [], 'needsReview': [], 'completedToday': [], 'nextActions': []
})
pending_count, pending_items = parse_pending_count()
git_health = parse_git_state()
mem_health = parse_critical_facts()
bee_sync = parse_bee_sync_last_run()

system = [
    {'label': 'Gateway/Agent Reachable', 'severity': 'ok'},
    {'label': 'Cron Scheduler Enabled', 'severity': 'ok'},
    bee_sync,
    git_health,
    mem_health,
    {'label': f'Pending Promotions: {pending_count}', 'severity': 'warn' if pending_count else 'ok'}
]

payload = {
    'updatedAt': datetime.now().isoformat(),
    'kpis': {
        'nowRunning': len(feed.get('activeWork', [])),
        'blocked': len(feed.get('blocked', [])),
        'needsReview': len(feed.get('needsReview', [])),
        'completedToday': len(feed.get('completedToday', [])),
        'pendingPromotions': pending_count
    },
    'systemHealth': system,
    'activeWork': feed.get('activeWork', []),
    'blocked': feed.get('blocked', []),
    'needsReview': feed.get('needsReview', []),
    'completedToday': feed.get('completedToday', []),
    'nextActions': feed.get('nextActions', []),
    'pendingPromotions': pending_items
}

data_str = json.dumps(payload, indent=2)
OUT.write_text(data_str, encoding='utf-8')
OUT_ROOT.write_text(data_str, encoding='utf-8')
print(OUT)
