<?php
/**
 * List-logs use case.
 *
 * Phase 11 slice 11d Application-layer use case that drives the
 * §12.2 `GET /affilun/v1/logs` REST surface documented in
 * `specifications/rest-api-spec.md`. The use case is a thin
 * orchestration seam between the persistence-layer query surface
 * ({@see LogRepository::findPaginated()}) and the masking pipeline
 * ({@see LogMasker::maskRecord()}) — it does NOT own filter
 * validation (that lives on
 * {@see \Affilun\Infrastructure\Persistence\LogListQuery})
 * and does NOT own envelope construction (that lives on the REST
 * controller).
 *
 * @package Affilun\Application\Logs\UseCase
 */

declare(strict_types=1);

namespace Affilun\Application\Logs\UseCase;

use Affilun\Application\Logs\LogMasker;
use Affilun\Infrastructure\Persistence\LogListQuery;
use Affilun\Infrastructure\Persistence\LogRepository;

/**
 * Application-layer use case for `GET /affilun/v1/logs` (§12.2).
 *
 * See the file-level docblock for the orchestration shape: query
 * → repository → masker → result VO.
 */
final class ListLogsUseCase {

	/**
	 * Persistence-layer query surface.
	 */
	private LogRepository $logs;

	/**
	 * Row-shape masker driving the §12.2 envelope projection.
	 */
	private LogMasker $masker;

	/**
	 * Construct the use case with explicit collaborator
	 * injection.
	 *
	 * @param LogRepository $logs   Persistence-layer query surface.
	 * @param LogMasker     $masker Row-shape masker.
	 */
	public function __construct( LogRepository $logs, LogMasker $masker ) {
		$this->logs   = $logs;
		$this->masker = $masker;
	}

	/**
	 * Execute the §12.2 list-logs query.
	 *
	 * Calls {@see LogRepository::findPaginated()} with the supplied
	 * query VO, projects every returned
	 * {@see \Affilun\Infrastructure\Persistence\LogRecord}
	 * through {@see LogMasker::maskRecord()}, and wraps the result
	 * in a {@see ListLogsResult} carrying the pagination axes
	 * echoed back from the query.
	 *
	 * @param LogListQuery $query Validated list-query inputs.
	 */
	public function execute( LogListQuery $query ): ListLogsResult {
		$page = $this->logs->findPaginated( $query );

		$items = array();
		foreach ( $page->items() as $record ) {
			$items[] = $this->masker->maskRecord( $record );
		}

		return new ListLogsResult(
			$items,
			$page->total(),
			$page->page(),
			$page->perPage(),
			$page->pageCount()
		);
	}
}
