package de.gecheckt.pdf.umbenenner.bootstrap.startup;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;

/**
 * Liest die Log-Verzeichnis-Angabe so früh wie möglich aus der aktiven Konfigurationsdatei
 * und setzt sie als System-Property {@code log.directory}, bevor Log4j2 zum ersten Mal
 * initialisiert wird.
 * <p>
 * Hintergrund: {@code log4j2.xml} referenziert {@code ${sys:log.directory}} für den
 * Pfad der Rolling-File-Datei. Da Log4j2 sich beim ersten {@code LogManager}-Aufruf
 * einmalig konfiguriert, muss die System-Property bereits vorher gesetzt sein. Greift
 * die Property nicht, fällt {@code log4j2.xml} auf ein nutzerschreibbares
 * Default-Verzeichnis zurück, damit auch im MSI-Betrieb (Arbeitsverzeichnis unter
 * {@code Program Files}, typischerweise nicht beschreibbar) eine Log-Datei entsteht.
 * <p>
 * Diese Klasse vermeidet bewusst jede Logger-Nutzung und schluckt sämtliche Fehler:
 * Sie soll niemals den Programmstart verhindern, sondern lediglich einen frühen
 * Best-Effort-Hinweis an Log4j2 liefern.
 */
public final class EarlyLogDirectoryInitializer {

    private static final String SYSTEM_PROPERTY_KEY = "log.directory";
    private static final String CONFIG_OPTION = "--config";
    private static final Path DEFAULT_CONFIG_PATH = Paths.get("config/application.properties");
    private static final String CONFIG_PROPERTY_KEY = "log.directory";

    private EarlyLogDirectoryInitializer() {
        // utility
    }

    /**
     * Versucht, aus der aktiven Konfigurationsdatei den Wert von {@code log.directory}
     * zu lesen, und setzt ihn als System-Property, sofern er ein nicht-leerer String ist.
     * <p>
     * Greift {@code --config <pfad>} auf, ansonsten {@code config/application.properties}
     * relativ zum Arbeitsverzeichnis. Ist kein Wert ableitbar, bleibt die System-Property
     * unverändert; in diesem Fall greift der in {@code log4j2.xml} hinterlegte Fallback.
     *
     * @param args Kommandozeilenargumente, dürfen {@code null} sein
     */
    public static void applyFromArgs(String[] args) {
        try {
            if (System.getProperty(SYSTEM_PROPERTY_KEY) != null
                    && !System.getProperty(SYSTEM_PROPERTY_KEY).isBlank()) {
                return;
            }
            Path configPath = resolveConfigPath(args);
            if (configPath == null || !Files.isRegularFile(configPath)) {
                return;
            }
            Properties properties = new Properties();
            try (InputStream in = Files.newInputStream(configPath)) {
                properties.load(in);
            }
            String value = properties.getProperty(CONFIG_PROPERTY_KEY);
            if (value != null && !value.isBlank()) {
                System.setProperty(SYSTEM_PROPERTY_KEY, value.trim());
            }
        } catch (IOException | RuntimeException ignored) {
            // bewusst still: Log4j2-Fallback aus log4j2.xml übernimmt ansonsten
        }
    }

    private static Path resolveConfigPath(String[] args) {
        if (args != null) {
            for (int i = 0; i < args.length - 1; i++) {
                if (CONFIG_OPTION.equals(args[i])) {
                    String raw = args[i + 1];
                    if (raw != null && !raw.isBlank()) {
                        try {
                            return Paths.get(raw);
                        } catch (RuntimeException ignored) {
                            return null;
                        }
                    }
                }
            }
        }
        return DEFAULT_CONFIG_PATH;
    }
}
