<?php

namespace Planaday\Utility\Debug\Log;

use Planaday\Utility\DependencyInjection\Attributes\InjectionMethod;
use Planaday\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\DependencyInjection\Scope;

trait Logging {
	protected bool $logDebug = true;
	protected ?Logger $logger = null;
	protected array $logBuffer = [];
	public string $loggingScopeId = "global/unset/none";

	#[InjectionMethod]
	public function setLogger(Logger $logger, #[Scoped] ?Scope $scope = null): void {
		$this->logger = $logger;
		$this->loggingScopeId = $scope->scopeId ?? "global/unset/none";
		$this->logDebug = &$logger->logDebug;
		foreach ($this->logBuffer as $log){
			$this->logger->log($log->setScopeId( $this->loggingScopeId));
		}
		$this->logBuffer = [];
	}

	/**
	 * @param string $message
	 * @param mixed $data
	 *
	 * @return void
	 */
	protected function logInfo(string $message, $data = null): void {
		$this->log('info', $message, microtime(true), $data);
	}

	/**
	 * @param string $message
	 * @param mixed $data
	 *
	 * @return void
	 */
	protected function logDebug(string $message, $data = null): void {
		if (!$this->logDebug) return;
		$this->log('debug', $message, microtime(true), $data);
	}

	/**
	 * @param string $message
	 * @param mixed $data
	 *
	 * @return void
	 */
	protected function logWarning(string $message, $data = null): void {
		$this->log('warning', $message, microtime(true), $data);
	}

	/**
	 * @param string $message
	 * @param mixed $data
	 *
	 * @return void
	 */
	protected function logError(string $message, $data = null): void {
		$this->log('error', $message, microtime(true), ['trace' => debug_backtrace(0), 'data' => $data]);
	}

	private function log(string $type, string $message, float $time, mixed $data = null):void {
		$log = (new LogEntry())
			->setType( $type )
			->setMessage( $message )
			->setRawTime( $time * 1000 )
			->setTime( date("Y-m-d H:m:s", (int)floor( $time)) .
			           '.' . substr(number_format(((int)($time * 1000) % 1000) + 1000),2) . ' GMT')
			->setData( $data )
			->setClass( get_class($this) );

		if ($this->logger === null) {
			$this->logBuffer[] = $log;
		} else {
			$this->logger->log($log->setScopeId( $this->loggingScopeId ));
		}
	}
}