/**
 * Öffnen und Anzeigen von Dateien, die diese Anwendung selbst geschrieben hat.
 *
 * **Wozu.** Alle Druckausgaben und die Sicherung endeten bis 0.22.0 mit einem
 * reinen Textsatz samt Pfad: „Der Lernbericht wurde gespeichert: …“. Wer die
 * eben erzeugte Fragenliste drucken oder die Sicherung auf einen Stick ziehen
 * wollte, musste den Pfad ablesen und im Explorer selbst hinnavigieren — nach
 * „Speichern unter“ die unbequemste Fortsetzung, die ein Programm anbieten
 * kann.
 *
 * **Warum eine Merkliste und keine Pfadprüfung.** Der Renderer schickt keinen
 * Pfad, sondern eine Kennung: Wer einen Pfad mitbringen darf, darf auch einen
 * anderen mitbringen — dieselbe Überlegung wie beim unterbrochenen
 * Prüfungsbogen und beim Einspielweg der Sicherung. Der Hauptprozess merkt
 * sich, was er in dieser Sitzung selbst geschrieben hat, und öffnet
 * ausschließlich das. Eine Prüfung „liegt der Pfad unter Dokumente?“ wäre
 * schwächer: Auch dort kann etwas liegen, das diese Anwendung nichts angeht.
 *
 * **Was hier nicht passiert.** `shell.openPath` überlässt dem Betriebssystem,
 * womit eine Datei geöffnet wird. Das ist bei einem PDF gewollt und bei einer
 * Datei unbekannter Herkunft eine Einladung — deshalb kommt in die Merkliste
 * nur, was diese Anwendung soeben selbst erzeugt hat.
 */

import { shell } from 'electron';

/**
 * Was in dieser Sitzung geschrieben wurde, mit Kennung.
 *
 * Nur im Arbeitsspeicher: Nach einem Neustart ist die Liste leer, und ein
 * alter Verweis führt dann nirgendwohin — richtig so, die Datei kann
 * inzwischen verschoben oder gelöscht sein.
 */
const geschrieben = new Map<string, string>();

let zaehler = 0;

/**
 * Merkt einen geschriebenen Pfad und gibt die Kennung zurück, unter der der
 * Renderer ihn öffnen lassen darf.
 */
export function geschriebenMerken(pfad: string): string {
  zaehler += 1;
  const kennung = `datei-${String(zaehler)}`;
  geschrieben.set(kennung, pfad);
  return kennung;
}

/** Was zu tun ist. */
export type Dateiwunsch = 'oeffnen' | 'ordner';

/**
 * Öffnet die Datei oder zeigt sie im Dateimanager.
 *
 * @returns `false`, wenn die Kennung unbekannt ist oder das System die Datei
 *   nicht öffnen konnte – etwa weil sie inzwischen verschoben wurde.
 */
export async function dateiZeigen(kennungRoh: unknown, wunsch: Dateiwunsch): Promise<boolean> {
  const kennung = typeof kennungRoh === 'string' ? kennungRoh : '';
  const pfad = geschrieben.get(kennung);
  if (pfad === undefined) {
    return false;
  }

  if (wunsch === 'ordner') {
    /* Zeigt den Ordner und markiert die Datei darin. Liefert nichts zurück –
       ob es geklappt hat, ist von hier aus nicht feststellbar. */
    shell.showItemInFolder(pfad);
    return true;
  }

  /* `openPath` liefert eine leere Zeichenkette bei Erfolg und sonst die
     Fehlermeldung des Systems. */
  const fehler = await shell.openPath(pfad);
  if (fehler !== '') {
    console.warn(`[datei] konnte nicht geöffnet werden: ${fehler}`);
    return false;
  }
  return true;
}

/** Gegenstück für Tests. */
export function geschriebeneVergessen(): void {
  geschrieben.clear();
  zaehler = 0;
}
