<?php namespace RVR\Cli;

use DateTime;
use SokoWeb\Database\Query\Modify;
use SokoWeb\Database\Query\Select;
use SokoWeb\Interfaces\Database\IResultSet;
use RVR\Repository\UserPasswordResetterRepository;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MaintainDatabaseCommand extends Command
{
    private UserPasswordResetterRepository $userPasswordResetterRepository;

    public function __construct()
    {
        parent::__construct();

        $this->userPasswordResetterRepository = new UserPasswordResetterRepository();
    }

    public function configure(): void
    {
        $this->setName('db:maintain')
            ->setDescription('Maintain database.');
    }

    public function execute(InputInterface $input, OutputInterface $output): int
    {
        try {
            $this->deleteExpiredPasswordResetters();
            $this->deleteExpiredSessions();
        } catch (\Exception $e) {
            $output->writeln('<error>Maintenance failed!</error>');
            $output->writeln('');

            $output->writeln((string) $e);
            $output->writeln('');

            return 1;
        }

        $output->writeln('<info>Maintenance was successful!</info>');
        $output->writeln('');

        return 0;
    }

    private function deleteExpiredPasswordResetters(): void
    {
        foreach ($this->userPasswordResetterRepository->getAllExpired() as $passwordResetter) {
            \Container::$persistentDataManager->deleteFromDb($passwordResetter);
        }
    }

    private function deleteExpiredSessions(): void
    {
        //TODO: model may be used for sessions too
        $select = new Select(\Container::$dbConnection, 'sessions');
        $select->columns(['id']);
        $select->where('updated', '<', (new DateTime('-7 days'))->format('Y-m-d H:i:s'));

        $result = $select->execute();

        while ($session = $result->fetch(IResultSet::FETCH_ASSOC)) {
            $modify = new Modify(\Container::$dbConnection, 'sessions');
            $modify->setId($session['id']);
            $modify->delete();
        }
    }
}