<commit_before><?php

namespace RodrigoPedra\RecordProcessor\Stages;

use League\Csv\Reader as RawCSVReader;
use RodrigoPedra\RecordProcessor\Contracts\ProcessorStageFlusher;
use RodrigoPedra\RecordProcessor\Helpers\FileInfo;
use RodrigoPedra\RecordProcessor\Stages\TransferObjects\FlushPayload;
use RuntimeException;
use SplFileInfo;
use SplFileObject;
use function RodrigoPedra\RecordProcessor\value_or_null;

class DownloadFileOutput implements ProcessorStageFlusher
{
    /** @var FileInfo */
    protected $downloadFileInfo;

    public function __construct( $fileName = '' )
    {
        $fileName = value_or_null( $fileName );

        $this->downloadFileInfo = is_null( $fileName )
            ? null
            : new FileInfo( $fileName );
    }

    public function flush( FlushPayload $payload )
    {
        $output = $payload->getOutput();

        if (!is_object( $output )) {
            throw new RuntimeException( 'Output is not a SplFileInfo object' );
        }

        if (!$output instanceof SplFileInfo) {
            throw new RuntimeException( 'Output is not a SplFileInfo object' );
        }

        $realPath = $output->getRealPath();

        if ($realPath === false) {
            throw new RuntimeException( "File {$realPath} does not exist" );
        }

        $fileInfo = new FileInfo( $realPath );

        if (is_null( $this->downloadFileInfo )) {
            $this->downloadFileInfo = $fileInfo;
        }

        if ($fileInfo->isCSV()) {
            $this->downloadWithLeagueCSV( $fileInfo );

            return $payload;
        }

        $this->outputContent( $fileInfo );

        return $payload;
    }

    protected function outputContent( FileInfo $fileInfo )
    {
        $this->outputHeaders( $fileInfo );

        $downloadFile = new SplFileObject( $fileInfo->getRealPath(), 'rb' );
        $downloadFile->rewind();
        $downloadFile->fpassthru();

        die;
    }

    protected function outputHeaders( FileInfo $fileInfo )
    {
        header( 'Content-Type: ' . $fileInfo->guessMimeType() . '; charset=utf-8' );
        header( 'Content-Transfer-Encoding: binary' );
        header( 'Content-Description: File Transfer' );

        $filename = rawurlencode( $this->downloadFileInfo->getBasename() );
        header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
    }

    protected function downloadWithLeagueCSV( FileInfo $fileInfo )<commit_msg>extracted file info to method<commit_after><?php

namespace RodrigoPedra\RecordProcessor\Stages;

use League\Csv\Reader as RawCSVReader;
use RodrigoPedra\RecordProcessor\Contracts\ProcessorStageFlusher;
use RodrigoPedra\RecordProcessor\Helpers\FileInfo;
use RodrigoPedra\RecordProcessor\Stages\TransferObjects\FlushPayload;
use RuntimeException;
use SplFileInfo;
use SplFileObject;
use function RodrigoPedra\RecordProcessor\value_or_null;

class DownloadFileOutput implements ProcessorStageFlusher
{
    /** @var FileInfo */
    protected $downloadFileInfo;

    public function __construct( $fileName = '' )
    {
        $fileName = value_or_null( $fileName );

        $this->downloadFileInfo = is_null( $fileName )
            ? null
            : new FileInfo( $fileName );
    }

    public function flush( FlushPayload $payload )
    {
        $fileInfo = $this->getOutputFileInfo( $payload );

        if (is_null( $this->downloadFileInfo )) {
            $this->downloadFileInfo = $fileInfo;
        }

        if ($fileInfo->isCSV()) {
            $this->downloadWithLeagueCSV( $fileInfo );

            return $payload;
        }

        $this->downloadFile( $fileInfo );

        return $payload;
    }

    protected function getOutputFileInfo( FlushPayload $payload )
    {
        $output = $payload->getOutput();

        if (!is_object( $output )) {
            throw new RuntimeException( 'Output is not a SplFileInfo object' );
        }

        if (!$output instanceof SplFileInfo) {
            throw new RuntimeException( 'Output is not a SplFileInfo object' );
        }

        $realPath = $output->getRealPath();

        if ($realPath === false) {
            throw new RuntimeException( "File {$realPath} does not exist" );
        }

        return new FileInfo( $realPath );
    }

    protected function downloadFile( FileInfo $fileInfo )
    {
        $this->outputHeaders( $fileInfo );

        $downloadFile = new SplFileObject( $fileInfo->getRealPath(), 'rb' );
        $downloadFile->rewind();
        $downloadFile->fpassthru();

        die;
    }

    protected function outputHeaders( FileInfo $fileInfo )
    {
        header( 'Content-Type: ' . $fileInfo->guessMimeType() . '; charset=utf-8' );
        header( 'Content-Transfer-Encoding: binary' );
        header( 'Content-Description: File Transfer' );

        $filename = rawurlencode( $this->downloadFileInfo->getBasename() );
        header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
    }

    protected function downloadWithLeagueCSV( FileInfo $fileInfo )
{'fraction_non_alphanumeric': 0.1151394422310757, 'fraction_numerical': 0.00039840637450199205, 'mean_word_length': 2.738644825018615, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2134683', 'n_tokens_mistral': 1448, 'n_tokens_neox': 1398, 'n_words': 316}