#!/usr/bin/env python3
"""Document « Éléments à faire valider par un juriste » (bibliothèque du panneau de contrôle, catégorie Juridique) : accès réservé à l'équipe, contenu présent, et LIEN AVEC LE CODE pour qu'il ne se périme pas
en silence : chaque table « conservée » du registre de suppression de compte y figure, chaque réglage cité existe dans /control, chaque table citée existe."""
import json, os, re, subprocess, sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from lib import ROOT, call, mk_user, ok, reset_rate_limits, sql, summary

def php(code): return subprocess.run(['php', '-d', 'display_errors=0', '-r', '$_SERVER["REQUEST_METHOD"]="GET"; require "api/_account_delete.php"; ' + code], capture_output=True, text=True, cwd=ROOT).stdout.strip()
sql("DELETE FROM users WHERE id LIKE 'lr\\_%'")
for uid, role in (('lr_admin', 'admin'), ('lr_resp', 'responsable'), ('lr_member', 'client_essentiel')): mk_user(uid, role, 'Prenom', uid)
reset_rate_limits(); SLUG = 'elements-a-valider-par-un-juriste'
st, d, _ = call('GET', 'lr_admin', '/admin-documents'); docs = d.get('documents', d) if isinstance(d, dict) else d
flat = json.dumps(d, ensure_ascii=False); ok(st == 200 and SLUG in flat and 'Éléments à faire valider par un juriste' in flat and 'contrat-commission-artisan' in flat, 'la bibliothèque du panneau liste le document dans la catégorie « Juridique », à côté du contrat de commission')
st, d, _ = call('GET', 'lr_resp', f'/admin-documents/juridique/{SLUG}'); doc = d.get('content', ''); ok(st == 200 and d.get('exists') is not False and len(doc) > 5000 and d['titre'] == 'Éléments à faire valider par un juriste', 'un responsable peut le lire (contenu complet)')
ok(call('GET', 'lr_member', f'/admin-documents/juridique/{SLUG}')[0] == 403 and call('GET', None, f'/admin-documents/juridique/{SLUG}')[0] in (401, 403), 'un membre ou un visiteur ne peut pas le lire (403 / 401)')
ok(call('GET', 'lr_admin', '/admin-documents/juridique/inexistant')[0] in (404, 400), 'un document hors liste blanche est refusé')
heads = re.findall(r'^## (\d+)\. (.+)$', doc, re.M); ok([h[0] for h in heads] == [str(i) for i in range(10)], f'10 rubriques numérotées de 0 à 9 ({", ".join(h[1][:28] for h in heads[:4])}…)')
ok('PAS un avis juridique' in doc and 'à confirmer' in doc, 'le document dit lui-même qu\'il n\'est pas un avis juridique et que les cadres cités sont des pistes à confirmer')
ok(all(re.search(r'^' + re.escape(n) + r' ', doc, re.M) for n in ('1.1', '1.2', '3.4', '5.1', '6.1', '8.4')) and 'URGENTE' in doc, 'les points critiques y sont (conservation comptable, messages privés, lecture des messages signalés, faille corrigée, export des données, contrat de commission)')

POLICY = json.loads(php('echo json_encode(ACCOUNT_DELETE_POLICY);')); keep = [t for t, v in POLICY.items() if v[1] == 'keep']
missing = [t for t in keep if t not in doc]; ok(not missing, f'TOUTE table « conservée » du registre de suppression de compte figure dans le document ({len(keep)} tables)' + (f' — absentes : {missing}' if missing else ''))
tables = set(sql("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()").split('\n')); cited = set(re.findall(r'`([a-z][a-z_]+)`', doc)); gone = sorted(c for c in cited if c in POLICY or c in ('candidatures',) if c not in tables)
ok(not gone, 'toute table citée dans le document existe encore' + (f' — disparues : {gone}' if gone else ''))
st, s, _ = call('GET', 'lr_admin', '/admin-messaging-settings'); keys = {x['key'] for x in s['settings']}; cols = set(sql("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'users'").split('\n'))
setting_like = sorted(c for c in cited if re.search(r'(_days|_months|_enabled|_weekday|_hour|_cap|auto_posts_(action|parcours)_)', c)); unknown = [c for c in setting_like if c not in keys]
ok(st == 200 and len(setting_like) >= 10 and not unknown, f'chaque réglage cité existe dans /control ({len(setting_like)} réglages vérifiés)' + (f' — inconnus : {unknown}' if unknown else ''))
colcited = [c for c in cited if c in ('auto_posts_optin', 'auto_posts_optin_at', 'fil_hide_auto', 'last_active_at', 'show_activity')]; ok(len(colcited) == 5 and all(c in cols for c in colcited), 'chaque colonne de membre citée (accord, masquage, activité) existe')
defaults = {'conversation_purge_days': 30, 'report_copy_retention_months': 6, 'audit_retention_months': 12, 'notifications_retention_days': 90, 'moderation_context_messages': 10, 'activity_window_days': 7}
S = {x['key']: x for x in s['settings']}; bad = [k for k, v in defaults.items() if S[k]['default'] != v or not re.search(re.escape(k) + r'`[^.]*?\(' + (str(v)) + r' ', doc)]
ok(not bad, 'les valeurs par défaut écrites dans le document (30 jours, 6 mois, 12 mois, 90 jours, 10 messages, 7 jours) sont celles de /control' + (f' — écarts : {bad}' if bad else ''))
sql("DELETE FROM users WHERE id LIKE 'lr\\_%'"); summary()
