<?php

namespace Wrm\Events\Service\Cleanup;

/*
 * Copyright (C) 2019 Daniel Siepmann <coding@daniel-siepmann.de>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;

class Database
{
    /**
     * @var ConnectionPool
     */
    private $connectionPool;

    private const DATE_TABLE = 'tx_events_domain_model_date';
    private const EVENT_TABLE = 'tx_events_domain_model_event';
    private const ORGANIZER_TABLE = 'tx_events_domain_model_organizer';

    public function __construct(
        ConnectionPool $connectionPool
    ) {
        $this->connectionPool = $connectionPool;
    }

    public function truncateTables(): void
    {
        $tableNames = [
            Database::DATE_TABLE,
            Database::ORGANIZER_TABLE,
            Database::EVENT_TABLE,
        ];

        foreach ($tableNames as $tableName) {
            $this->connectionPool
                ->getConnectionForTable($tableName)
                ->truncate($tableName);
        }
        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_category_record_mm');
        $queryBuilder->delete('sys_category_record_mm')
            ->where($queryBuilder->expr()->like(
                'tablenames',
                $queryBuilder->createNamedParameter('tx_events_domain_model_%')
            ))
            ->execute();
    }

    public function deletePastDates(): void
    {
        $queryBuilder = $this->connectionPool
            ->getConnectionForTable(self::DATE_TABLE)
            ->createQueryBuilder();

        $queryBuilder->getRestrictions()->removeAll();

        $midnightToday = new \DateTimeImmutable('midnight today');
        $queryBuilder->delete(self::DATE_TABLE)
            ->where($queryBuilder->expr()->lte(
                'end',
                $queryBuilder->createNamedParameter($midnightToday->format('U'))
            ))
            ->execute();
    }

    public function deleteEventsWithoutDates(): void
    {
        $queryBuilder = $this->connectionPool
            ->getConnectionForTable(self::EVENT_TABLE)
            ->createQueryBuilder();

        $queryBuilder->getRestrictions()->removeAll();

        $recordUids = $queryBuilder->select('event.uid')
            ->from(self::EVENT_TABLE, 'event')
            ->leftJoin('event', self::DATE_TABLE, 'date', $queryBuilder->expr()->eq('date.event', 'event.uid'))
            ->where($queryBuilder->expr()->isNull('date.uid'))
            ->execute()
            ->fetchAll(\PDO::FETCH_COLUMN);

        $queryBuilder = $this->connectionPool->getQueryBuilderForTable(self::EVENT_TABLE);
        $queryBuilder->delete(self::EVENT_TABLE);
        $queryBuilder->where($queryBuilder->expr()->in(
            'uid',
            $queryBuilder->createNamedParameter($recordUids, Connection::PARAM_INT_ARRAY)
        ));
        $queryBuilder->execute();

        $queryBuilder = $this->connectionPool->getQueryBuilderForTable('sys_category_record_mm');
        $queryBuilder->delete('sys_category_record_mm')
            ->where($queryBuilder->expr()->andX(
                $queryBuilder->expr()->like(
                    'tablenames',
                    $queryBuilder->createNamedParameter('tx_events_domain_model_%')
                ),
                $queryBuilder->expr()->in(
                    'uid_foreign',
                    $queryBuilder->createNamedParameter($recordUids, Connection::PARAM_INT_ARRAY)
                )
            ))
            ->execute();
    }
}