// @vitest-environment node
/**
 * Prüfhilfen an der IPC-Grenze.
 *
 * `entschaerft` bereinigt alles, was aus dem Renderer in eine Fehlermeldung,
 * ins Protokoll oder in einen Profilnamen gelangt. Die Funktion war bis zur
 * Abnahme von keinem Test abgedeckt – und stand zugleich in zwei Fassungen im
 * Baum, sodass eine Verschärfung nur an einer Stelle gegriffen hätte.
 */

import { describe, expect, it } from 'vitest';

import { entschaerft } from '../src/main/eingaben';

describe('entschaerft', () => {
  it('lässt harmlosen Text unangetastet', () => {
    expect(entschaerft('Olaf Willerding')).toBe('Olaf Willerding');
    expect(entschaerft('Frage I.1-04 – Schusswaffen?')).toBe('Frage I.1-04 – Schusswaffen?');
  });

  it('ersetzt klassische Steuerzeichen', () => {
    expect(entschaerft('a\nb')).toBe('a?b');
    expect(entschaerft('a\rb')).toBe('a?b');
    expect(entschaerft('a\tb')).toBe('a?b');
    /* Als Escape-Sequenz und nicht als rohes Byte: Ein Nullzeichen in der
       Datei macht sie für Git zur Binärdatei – kein Diff, keine
       Zeilenenden-Normalisierung, keine Anzeige im Verlauf. Genau das war
       hier bis Fassung 0.24.1 der Fall, und der Modulkopf von
       `main/schema.ts` warnt an anderer Stelle ausdrücklich davor. */
    expect(entschaerft('a\u0000b')).toBe('a?b');
    expect(entschaerft('ab')).toBe('a?b');
  });

  it('ersetzt Escape-Sequenzen, mit denen sich ein Terminal steuern lässt', () => {
    // „[2J" löscht in vielen Terminals den Bildschirm.
    expect(entschaerft('[2Jharmlos')).toBe('?[2Jharmlos');
  });

  it('ersetzt bidirektionale Steuerzeichen', () => {
    /* U+202E kehrt die Anzeigerichtung um. Ohne diese Reinigung könnte eine
       Meldung etwas völlig anderes zeigen, als sie enthält. */
    expect(entschaerft('Datei‮gnp.exe')).toBe('Datei?gnp.exe');
    expect(entschaerft('a‎b‏c')).toBe('a?b?c');
    expect(entschaerft('a⁦b⁩c')).toBe('a?b?c');
  });

  it('ersetzt Zeilen- und Absatztrenner, die keine sind', () => {
    // U+2028/U+2029 brechen eine Logzeile auf, ohne wie ein Umbruch auszusehen.
    expect(entschaerft('a b')).toBe('a?b');
    expect(entschaerft('a b')).toBe('a?b');
  });

  it('ersetzt den C1-Bereich und die Bytereihenfolge-Marke', () => {
    expect(entschaerft('ab')).toBe('a?b');
    expect(entschaerft('a﻿b')).toBe('a?b');
  });

  it('kürzt auf 80 Zeichen', () => {
    expect(entschaerft('x'.repeat(200))).toHaveLength(80);
  });

  it('zerteilt beim Kürzen kein Emoji', () => {
    /* Nach UTF-16-Einheiten gekürzt bliebe ein halbes Surrogatpaar übrig –
       eine ungültige Zeichenkette, die je nach Ausgabe als Fragezeichen oder
       als Fehler erscheint. */
    expect(entschaerft('🔫'.repeat(100))).toBe('🔫'.repeat(80));
  });

  it('zerlegt auch zusammengesetzte Zeichen nicht', () => {
    /* Eine Flagge besteht aus zwei Regionalindikatoren, ein Buchstabe mit
       Akzent aus Grundzeichen und Kombinationszeichen. Nach Codepoints
       gekürzt zerfielen sie in ihre Bestandteile und zeigten etwas anderes
       an als vorher. */
    expect(entschaerft('🇩🇪'.repeat(100))).toBe('🇩🇪'.repeat(80));
    expect(entschaerft('é'.repeat(100))).toBe('é'.repeat(80));
  });

  it('nimmt ein eigenes Ersatzzeichen entgegen', () => {
    expect(entschaerft('a\nb', '_')).toBe('a_b');
    expect(entschaerft('a\nb', '')).toBe('ab');
  });

  it('macht aus Nicht-Zeichenketten eine lesbare Angabe', () => {
    expect(entschaerft(42)).toBe('42');
    expect(entschaerft(null)).toBe('null');
    expect(entschaerft(undefined)).toBe('undefined');
    expect(entschaerft({ a: 1 })).toBe('[object Object]');
  });
});
