<?php
/**
 * @package Hafenstudios\Wellenbrecher
 */

namespace Hafenstudios\Wellenbrecher\Support;

defined( 'ABSPATH' ) || exit;

/**
 * Ein Ablageort fuer die Opt-in-Externa (W5b): die per Download geholten
 * DB-IP-Datenbanken und die aktualisierte Disposable-Liste liegen unter
 * wp-content/uploads/wellenbrecher/. Zentral, damit alle W5b-Klassen dieselbe
 * Pfad-Konvention benutzen und die Aufloesung testbar an EINER Stelle steht.
 *
 * Ohne WordPress (Unit-Tests) liefert dir() einen leeren String; die Aufrufer
 * behandeln das als "kein Ablageort" und verhalten sich fail-open.
 */
final class Uploads {

	public const SUBDIR = 'wellenbrecher';

	/**
	 * Absoluter Pfad des Ablage-Ordners MIT abschliessendem Schraegstrich, oder
	 * leer, wenn der Upload-Ordner nicht ermittelbar ist.
	 *
	 * @param bool $create Ordner bei Bedarf anlegen.
	 * @return string
	 */
	public static function dir( bool $create = false ): string {
		if ( ! function_exists( 'wp_upload_dir' ) ) {
			return '';
		}
		$upload = wp_upload_dir();
		if ( ! is_array( $upload ) || empty( $upload['basedir'] ) ) {
			return '';
		}
		$dir = rtrim( (string) $upload['basedir'], '/\\' ) . '/' . self::SUBDIR;
		if ( $create && ! is_dir( $dir ) && function_exists( 'wp_mkdir_p' ) ) {
			wp_mkdir_p( $dir );
		}
		return $dir . '/';
	}

	/**
	 * Absoluter Pfad einer Datei im Ablage-Ordner, oder leer.
	 *
	 * @param string $file Dateiname.
	 * @param bool   $create Ordner bei Bedarf anlegen.
	 * @return string
	 */
	public static function path( string $file, bool $create = false ): string {
		$dir = self::dir( $create );
		return '' === $dir ? '' : $dir . $file;
	}

	/**
	 * Schreibt eine Datei atomar (temp plus rename). Verhindert, dass ein
	 * abgebrochener Schreibvorgang eine halbe Datei hinterlaesst - Grundlage der
	 * W5b-Zusage "Fehlschlag = Bestand bleibt".
	 *
	 * @param string $path    Zielpfad.
	 * @param string $content Inhalt.
	 * @return bool
	 */
	public static function write_atomic( string $path, string $content ): bool {
		$tmp = $path . '.tmp';
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- eigene Datei im uploads-Ordner, atomar via rename.
		if ( false === file_put_contents( $tmp, $content ) ) {
			return false;
		}
		if ( ! @rename( $tmp, $path ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- Fehlschlag wird aufgeraeumt.
			@unlink( $tmp ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.unlink_unlink
			return false;
		}
		return true;
	}
}
