<?php

namespace Diamond\Repositories\ErrorLog;

use Propel\Runtime\ActiveQuery\ModelCriteria;
use Repo\CollectionInterface;
use Repo\CrudRepositoryBuilderInterface;
use Repo\EntityInterface;
use Repo\PaginationInterface;

class ErrorLog implements CrudRepositoryBuilderInterface
{
    /**
     * @param array $row
     * @param EntityInterface $entity
     * @return EntityInterface
     */
    public function buildEntityFromArray(array $row, EntityInterface $entity = null): EntityInterface
    {

        if(!$entity){
            $entity = self::createEntity();
        }

        return
            $entity
                ->setId($row['id'])
                ->setFileName($row['filename'])
                ->setSize($row['size'])
                ->setErrors($row['errors'])
                ->setDate($row['datetime'])
                ->setPathName($row['pathname']);
    }


    /**
     * @return \Repo\EntityInterface|ErrorLogEntity
     */
    public static function createEntity(): EntityInterface
    {
        return new ErrorLogEntity();
    }


    public function save(EntityInterface $entity): void
    {
        // TODO: Implement save() method.
    }

    /**
     * @param PaginationInterface|ErrorLogCriteria $criteria
     * @return CollectionInterface
     * @throws \Repo\Concrete\Exceptions\Collection
     */
    public function findByCriteria(PaginationInterface $criteria): CollectionInterface
    {

        $collection = $this->findAll();
        $filterCollection = new ErrorLogCollection();
        $i = 0;
        $max = $criteria->getLimit() * $criteria->getPage();
        $min = ($criteria->getLimit() * $criteria->getPage() - $criteria->getLimit())+1;

        $max = $max>0 ? $max: $criteria->getLimit();
        $min = $min<0?0:$min;

        foreach ($collection as $file) {

            if ($criteria->getFilterByFileName() && $file->getFileName() !== $criteria->getFilterByFileName()) {
                continue;
            }

            $i++;

            if (($i < $min || $i > $max ) && $criteria->getLimit() > 0 ) {
                continue;
            }
            
            $filterCollection->push($file);
        }

        return $filterCollection;
    }

    protected function findAll(): ErrorLogCollection
    {

        $finder = \Symfony\Component\Finder\Finder::create()
            ->files()
            ->in(BASEPATH . '/app/logs')
            ->sortByChangedTime()
            ->reverseSorting()
            ->name('errors_*.log');

        $collection = new ErrorLogCollection();
        foreach ($finder as $file) {


            /**
             * @var \SplFileInfo $file
             */
            if (preg_match('~errors_(\d{4}_\d{2}_\d{2})\.log~is', $file->getFilename(), $match)) {
                $date = \DateTime::createFromFormat('Y_m_d', $match[1]);
            } else {
                $date = (new \DateTime())->setTimestamp($file->getMTime());
            }

            $content = file_get_contents($file->getPathname());

            if (preg_match_all('~ERROR~', $content, $res)) {
                $count = count($res[0]);
            } else {
                $count = 0;
            }

            $collection->push(
                self::buildEntityFromArray([
                    'id' => md5($file->getFilename()),
                    'filename' => $file->getFilename(),
                    'size' => $file->getSize(),
                    'errors'=>$count,
                    'datetime' => $date,
                    'pathname' => $file->getPathname()
                ])
            );
        }

        return $collection;
    }


    public function count(?PaginationInterface $criteria): int
    {
        return $this->findAll()->count();
    }

    protected function modifyCriteria(PaginationInterface $criteria, ModelCriteria $dbCriteria): void
    {
        // TODO: Implement modifyCriteria() method.
    }

    public function delete(EntityInterface $entity): void
    {
        // TODO: Implement delete() method.
    }

    public function findById(int $id): ?EntityInterface
    {
        // TODO: Implement findById() method.
    }


}