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

namespace Hafenstudios\Core\Logging;

defined( 'ABSPATH' ) || exit;

/**
 * Schlankes, opt-in Logging (rotierend, ohne personenbezogene Inhalte).
 *
 * Standardmaessig aus. Aktivierung ueber die Option `hs_{namespace}_logging` oder
 * die Konstante HAFENSTUDIOS_DEBUG. Geschrieben wird in uploads/hafenstudios-logs/.
 */
final class Logger {

	private string $namespace;

	private const MAX_BYTES = 1048576; // 1 MB, dann Rotation.

	/**
	 * @param string $namespace Plugin-Slug.
	 */
	public function __construct( string $namespace ) {
		$this->namespace = sanitize_key( $namespace );
	}

	/**
	 * Ist Logging aktiv?
	 *
	 * @return bool
	 */
	public function is_enabled(): bool {
		if ( defined( 'HAFENSTUDIOS_DEBUG' ) && HAFENSTUDIOS_DEBUG ) {
			return true;
		}
		return (bool) get_option( 'hs_' . $this->namespace . '_logging', false );
	}

	/**
	 * Schreibt eine Zeile ins Log (nur wenn aktiviert).
	 *
	 * @param string               $level   info|warning|error.
	 * @param string               $message Nachricht (keine personenbezogenen Inhalte).
	 * @param array<string, mixed> $context Zusatzkontext (wird JSON-serialisiert).
	 * @return void
	 */
	public function log( string $level, string $message, array $context = array() ): void {
		if ( ! $this->is_enabled() ) {
			return;
		}

		$file = $this->file();
		if ( '' === $file ) {
			return;
		}

		if ( is_file( $file ) && filesize( $file ) > self::MAX_BYTES ) {
			@rename( $file, $file . '.1' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_rename
		}

		$line = sprintf(
			"[%s] %s.%s: %s %s\n",
			gmdate( 'Y-m-d H:i:s' ),
			$this->namespace,
			strtoupper( $level ),
			$message,
			$context ? wp_json_encode( $context ) : ''
		);

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
		@file_put_contents( $file, $line, FILE_APPEND | LOCK_EX );
	}

	/** @param string $m @param array<string,mixed> $c @return void */
	public function info( string $m, array $c = array() ): void {
		$this->log( 'info', $m, $c );
	}

	/** @param string $m @param array<string,mixed> $c @return void */
	public function warning( string $m, array $c = array() ): void {
		$this->log( 'warning', $m, $c );
	}

	/** @param string $m @param array<string,mixed> $c @return void */
	public function error( string $m, array $c = array() ): void {
		$this->log( 'error', $m, $c );
	}

	/**
	 * Pfad der Logdatei; legt das geschuetzte Verzeichnis bei Bedarf an.
	 *
	 * @return string
	 */
	private function file(): string {
		$uploads = wp_upload_dir();
		if ( ! empty( $uploads['error'] ) ) {
			return '';
		}
		$dir = trailingslashit( $uploads['basedir'] ) . 'hafenstudios-logs';
		if ( ! is_dir( $dir ) ) {
			wp_mkdir_p( $dir );
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
			@file_put_contents( $dir . '/.htaccess', "Deny from all\n" );
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
			@file_put_contents( $dir . '/index.php', "<?php // Silence is golden.\n" );
		}
		return $dir . '/' . $this->namespace . '.log';
	}
}
