import { readFileSync, readdirSync, statSync, existsSync } from 'fs';
import { join } from 'path';

const root = new URL('..', import.meta.url).pathname;
const read = rel => readFileSync(join(root, rel), 'utf8');
const failures = [];
const expect = (text, marker, label = marker) => { if (!text.includes(marker)) failures.push(`Fehlt: ${label}`); };
const forbid = (text, marker, label = marker) => { if (text.includes(marker)) failures.push(`Darf nicht enthalten sein: ${label}`); };

const pkg = JSON.parse(read('package.json'));
const lock = JSON.parse(read('package-lock.json'));
const manifest = JSON.parse(read('update-manifest.json'));
const server = read('server.mjs');
const auth = read('lib/auth.mjs');
const runtimePaths = read('lib/runtime-paths.mjs');
const dockerfile = read('Dockerfile');
const compose = read('compose.yaml');
const env = read('.env.example');
const html = read('public/index.html');
const app = read('public/app.js');
const setupPs = read('setup.ps1');
const setupSh = read('setup.sh');
const workflow = read('local-ai/workflows/vendoo_flux_schnell_api.json');

for (const [label, value] of [
  ['package.json', pkg.version], ['package-lock.json', lock.version],
  ['package-lock root', lock.packages?.['']?.version], ['update-manifest', manifest.version],
]) if (value !== '1.33.0') failures.push(`${label}-Version ist ${value}`);

for (const marker of ['content="1.33.0"', 'style.css?v=1.33.0', 'app.js?v=1.33.0']) expect(html, marker, `UI-Build ${marker}`);
if (!app.startsWith("const VENDOO_UI_BUILD = '1.33.0';")) failures.push('UI-Build ist nicht 1.33.0');
for (const marker of ["$Version = '1.33.0'", '?build=1.33.0']) expect(setupPs, marker, `Windows-Setup ${marker}`);

for (const marker of [
  "app.get('/healthz'", "app.get('/readyz'", 'gracefulShutdown', "process.once('SIGTERM'",
  'verifyRuntimeWritable', 'VENDOO_SETUP_TOKEN', 'VENDOO_EXTENSION_ORIGINS', 'setup_required: true',
  "app.use('/uploads', requireAuth", 'allowed.includes(ext) && isImageMime',
]) expect(server, marker);
for (const marker of ['VENDOO_DATA_DIR', 'VENDOO_DB_PATH', 'VENDOO_UPLOADS_DIR', 'VENDOO_BACKUP_DIR', 'VENDOO_OPERATIONS_DIR']) expect(runtimePaths, marker);
forbid(server, 'if (isSetupMode()) return next();', 'unsichere globale Setup-Auth-Ausnahme');

for (const marker of ['FROM node:22-bookworm-slim', 'npm ci --omit=dev', 'USER node', 'HEALTHCHECK', 'ENTRYPOINT']) expect(dockerfile, marker);
for (const marker of ['read_only: true', 'no-new-privileges:true', 'cap_drop:', 'vendoo_db:', 'vendoo_uploads:', 'vendoo_backups:', '/readyz', 'pids_limit: 256', 'max-size: "10m"', 'host.docker.internal:host-gateway']) expect(compose, marker);
for (const marker of ['VENDOO_SETUP_TOKEN=', 'VENDOO_COOKIE_SECURE=', 'VENDOO_COOKIE_SAMESITE=', 'VENDOO_EXTENSION_ORIGINS=']) expect(env, marker);
if (workflow.includes('LoadImage')) failures.push('Freier FLUX-Workflow enthält LoadImage');

for (const marker of [
  "Wo soll Vendoo betrieben werden?", 'Lokal auf diesem Windows-PC', 'Docker Desktop auf diesem Windows-PC',
  'NAS / Portainer / Docker-Server', 'VPS / öffentlicher Linux-Server', 'Install-VendooDocker',
  "Get-VendooInstallMode", "Set-VendooInstallMode 'docker'",
]) expect(setupPs, marker, `Windows-Deployment-Assistent ${marker}`);

if (!existsSync(join(root, 'setup.sh'))) failures.push('setup.sh fehlt');
for (const marker of [
  'Multiplatform Deployment Assistant', 'Docker auf diesem Linux-/Docker-Host',
  'NAS / Portainer / Docker-Host', 'VPS / öffentlicher Server hinter HTTPS-Reverse-Proxy',
  'compose build --pull', 'VENDOO_SETUP_TOKEN', 'docker-backup.sh', 'docker-restore.sh',
]) expect(setupSh, marker, `Linux-Deployment-Assistent ${marker}`);

for (const marker of [
  'id="flux-studio-reset"', 'Arbeitsbereich zurücksetzen', 'id="edit-user-email"',
  'type="button" class="primary-btn" id="edit-user-save-btn"',
]) expect(html, marker, `UI-Fix ${marker}`);
for (const marker of [
  'function resetFluxStudioWorkspace', "renderFluxStudioPreview(null)",
  "document.getElementById('flux-studio-reset')", 'data-user-edit=',
  'adminUsersCache', "button.textContent = 'Wird gespeichert …'",
]) expect(app, marker, `Frontend-Fix ${marker}`);
forbid(app, 'if (!state.fluxStudioCurrent && state.fluxStudioHistory[0])', 'automatische Auswahl des ersten FLUX-Historienbilds');
forbid(app, 'onclick="openEditUser(', 'fragile Inline-Benutzerbearbeitung');
for (const marker of ['return getUsers().find(user => Number(user.id) === Number(id)) || null;']) expect(auth, marker, 'sanitisierte Benutzerantwort nach Update');

function walk(dir, rel = '') {
  const out = [];
  for (const name of readdirSync(dir)) {
    const path = join(dir, name); const child = join(rel, name);
    if (statSync(path).isDirectory()) out.push(...walk(path, child)); else out.push(child.replaceAll('\\', '/'));
  }
  return out;
}
const forbiddenRuntime = walk(root).filter(rel =>
  /(^|\/)(vendoo\.db|\.env|node_modules|uploads|backups|operations|logs|runtime|data)(\/|$)/i.test(rel)
  && rel !== '.env.example'
);
if (forbiddenRuntime.length) failures.push(`Verbotene Laufzeitdaten im Paket: ${forbiddenRuntime.slice(0, 10).join(', ')}`);

if (failures.length) {
  console.error(`Deployment-Gate 1.33.0 fehlgeschlagen (${failures.length}):`);
  failures.forEach(item => console.error(`- ${item}`));
  process.exit(1);
}
console.log('Deployment-Gate 1.33.0 erfolgreich: Multiplatform-Assistent, Container-Härtung, leerer FLUX-Start, Reset und stabile Benutzerbearbeitung geprüft.');
