<?php
/**
 * A factory that builds a wrapper around the Monolog logger.
 * It always includes the standard logger: LoggerDBHandler and any additional loggers defined in the plugin settings.
 *
 * @since 3.0.0
 */

declare(strict_types=1);
namespace FeData\FastEvents\Logging;

defined( 'ABSPATH' ) || exit;

use FeData\FastEvents\Storage\PluginSettings;
use Monolog\Logger;
use stdClass;

/**
 * A class for creating a Monolog Logger.
 *
 * @mixin Logger
 */
final class LoggerFactory {

	/**
	 * Configuration of the Monolog logger.
	 *
	 * @since 3.0
	 * @var Logger
	 */
	private Logger $logger;

	/**
	 * LoggerFactory constructor.
	 *
	 * @since 3.0.0
	 *
	 * @param PluginSettings $settings Plugin settings.
	 */
	public function __construct( private readonly PluginSettings $settings ) {
		global $fevt_container;

		$config = $this->settings->monolog_config();

		$this->logger = new Logger( $config->channel ?? 'fast-events' );
		$this->logger->pushHandler( $fevt_container->get( LoggerDBHandler::class ) ); // Always add the DB handler.

		// Include all additional loggers.
		foreach ( $config->handlers ?? new stdClass() as $handler ) {
			if ( empty( $handler->class ) ) {
				error_log( 'Empty logger class found' ); //phpcs:ignore
				continue;
			}
			$class = $handler->class;
			$args  = (array) $handler->args ?? array();
			if ( ! class_exists( $class ) ) {
				error_log( 'Monolog: class ' . $class . ' not found' ); //phpcs:ignore
				continue;
			}
			$this->logger->pushHandler( new $class( ...$args ) );
		}
	}

	/**
	 * Singletons should not be cloneable.
	 *
	 * @since 2.5.0
	 */
	private function __clone(): void {
	}

	/**
	 * Prevent from being unserialized.
	 *
	 * @since 2.5.0
	 */
	public function __wakeup(): void {
	}

	/**
	 * Forward any other Monolog method to the inner logger
	 *
	 * @since 2.5.0
	 *
	 * @param string $method Monolog method name.
	 * @param array  $args   Arguments.
	 * @return mixed
	 */
	public function __call( string $method, array $args ) {
		return $this->logger->$method( ...$args );
	}
}
