<?php

namespace Tests\Traits;

use App\Actions\FetchArticleDataAction;
use App\Actions\FetchFeedArticlesAction;
use App\Actions\FetchRssArticlesAction;
use App\Actions\FetchWebsiteArticlesAction;
use App\Actions\SaveArticleAction;
use App\Services\Log\LogSaver;
use Mockery;
use Mockery\MockInterface;

trait CreatesFetchActions
{
    protected function createFeedFetcher(?LogSaver $logSaver = null): FetchFeedArticlesAction
    {
        $logSaver ??= $this->mockLogSaver();
        $saveArticle = new SaveArticleAction($logSaver);

        return new FetchFeedArticlesAction(
            $logSaver,
            new FetchRssArticlesAction($logSaver, $saveArticle),
            new FetchWebsiteArticlesAction($logSaver, $saveArticle),
        );
    }

    protected function createArticleDataFetcher(?LogSaver $logSaver = null): FetchArticleDataAction
    {
        return new FetchArticleDataAction($logSaver ?? $this->mockLogSaver());
    }

    /** @return array{FetchFeedArticlesAction, MockInterface} */
    protected function createFeedFetcherWithMockedLogSaver(): array
    {
        $logSaver = $this->mockLogSaver();

        return [$this->createFeedFetcher($logSaver), $logSaver];
    }

    /** @return LogSaver&MockInterface */
    private function mockLogSaver(): MockInterface
    {
        $logSaver = Mockery::mock(LogSaver::class);
        $logSaver->shouldReceive('info')->zeroOrMoreTimes();
        $logSaver->shouldReceive('warning')->zeroOrMoreTimes();
        $logSaver->shouldReceive('error')->zeroOrMoreTimes();
        $logSaver->shouldReceive('debug')->zeroOrMoreTimes();

        return $logSaver;
    }
}
