#!/usr/bin/env python3
"""Bandingkan kunci JSON yang dibaca layar aplikasi siswa dengan balasan API."""
import re, os, json, subprocess

BASE = os.environ.get('SIMAP_API', 'http://127.0.0.1:8081')
AKAR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MOBILE = os.path.join(AKAR, 'mobile_siswa') + '/'

def curl(jalur, tok):
    out = subprocess.run(['curl','-s',f'{BASE}/{jalur}','-H',f'Authorization: Bearer {tok}'],
                         capture_output=True, text=True).stdout
    try: return json.loads(out)
    except Exception: return None

tok = json.loads(subprocess.run(['curl','-s','-X','POST',f'{BASE}/auth/login',
      '-H','Content-Type: application/json',
      '-d', json.dumps({'username': 'rafi', 'password': 'simap123'})],
      capture_output=True, text=True).stdout)['data']['token']

uj = curl('siswa/ujian', tok)['data']
pid = next((u['peserta_id'] for u in uj if u.get('peserta_id')), None)
# Sesi ujian yang sedang berjalan, untuk memeriksa bentuk paket soal
uid = next((u['id'] for u in uj
            if str(u.get('status_saya')) == 'BERLANGSUNG'), None)

buku = curl('siswa/perpus', tok)['data']
bid = buku[0]['id'] if buku else None
mat = curl('siswa/materi', tok)['data']
mid = mat[0]['id'] if mat else None

PETA = {
    'lib/screens/beranda_screen.dart':   ['siswa/beranda'],
    'lib/screens/jadwal_screen.dart':    ['siswa/jadwal'],
    'lib/screens/belajar_screen.dart':   ['siswa/materi'],
    'lib/screens/materi_screen.dart':    [f'siswa/materi/{mid}'] if mid else [],
    'lib/screens/tugas_screen.dart':     ['siswa/tugas'],
    # Layar ujian memakai tiga endpoint: daftar, paket soal, dan hasil
    'lib/screens/ujian_screen.dart':     ['siswa/ujian']
        + ([f'siswa/ujian/{uid}/soal'] if uid else [])
        + ([f'siswa/ujian/hasil/{pid}'] if pid else []),
    'lib/screens/literasi_screen.dart':  ['siswa/literasi'],
    'lib/screens/perpus_screen.dart':    ['siswa/perpus'] + ([f'siswa/perpus/{bid}'] if bid else []),
    'lib/screens/peringkat_screen.dart': ['siswa/peringkat'],
    'lib/screens/profil_screen.dart':    ['siswa/beranda'],
}

def kumpulkan(o, h=None):
    if h is None: h = set()
    if isinstance(o, dict):
        for k, v in o.items(): h.add(k); kumpulkan(v, h)
    elif isinstance(o, list):
        for v in o[:5]: kumpulkan(v, h)
    return h

POLA = re.compile(r"""\[\s*['"]([a-z_][a-z0-9_]*)['"]\s*\]""", re.I)
# Kunci yang dipakai untuk MENGIRIM data, bukan membaca balasan
# Kunci pada balasan endpoint POST — diverifikasi terpisah lewat uji alur,
# tidak bisa diambil dengan permintaan GET biasa
BALASAN_POST = {'dihentikan','jumlah','maks','sisa','baru_tamat','poin','terlambat'}

KIRIM = {'foto_base64','nama_berkas','berkas_base64','buku_id','judul_luar',
         'halaman_awal','halaman_akhir','menit_baca','ringkasan','kesan','emosi',
         'jawaban','peserta_id','soal_id','sisa_detik','halaman','total_halaman','menit'}

ABAIKAN = {'data','ok','pesan','meta','token','simap_siswa_token','simap_siswa_server',
           'simap_siswa_nama','Authorization','Content-Type'} | KIRIM | BALASAN_POST

total = 0
for berkas, daftar in PETA.items():
    jalur = MOBILE + berkas
    if not os.path.isfile(jalur) or not daftar: continue

    tersedia, gagal = set(), False
    for e in daftar:
        r = curl(e, tok)
        if not r or not r.get('ok'):
            print(f"### {berkas}: API {e} GAGAL -> {str(r)[:80]}"); total += 1; gagal = True; continue
        tersedia |= kumpulkan(r.get('data'))
    if gagal: continue

    hilang = sorted(set(POLA.findall(open(jalur).read())) - ABAIKAN - tersedia)
    if hilang:
        print(f"### {berkas}   ({', '.join(daftar)})")
        for h in hilang:
            print(f"    '{h}' dibaca aplikasi, TIDAK ADA di balasan API"); total += 1
        print()

print(f"Layar diperiksa: {len(PETA)} | Ketidakcocokan: {total}")
