<?php
namespace Newland\NeosCommon\Command;

/*
 * This file is part of the "neos-common" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Neos\Flow\Cli\CommandController;
use Neos\Flow\Annotations as Flow;
use Neos\Neos\Domain\Model\Domain;
use Neos\Neos\Domain\Repository\DomainRepository;
use function \Safe\preg_replace;
use function \Safe\sprintf;

class DomainCommandController extends CommandController
{
    /**
     * @var array
     * @Flow\InjectConfiguration(path="domains.migrate")
     */
    protected $configuration;

    /**
     * @var DomainRepository
     * @Flow\Inject()
     */
    protected $domainRepository;

    /**
     * Replace all domains by pattern. Useful to replace preview with local domains.
     *
     * @example
     * $ php flow domain:migrate --pattern '/nimius-wip.de/' --replace 'ddev.local'
     * Modifying domain: tun-001.oehningen.nimius-wip.de => tun-001.oehningen.ddev.local.
     * Modifying domain: tun-001.nimius-wip.de => tun-001.ddev.local.
     * Modifying domain: tun-001.gaienhofen.nimius-wip.de => tun-001.gaienhofen.ddev.local.
     * Modifying domain: tun-001.radolfzell.nimius-wip.de => tun-001.radolfzell.ddev.local.
     * Modifying domain: tun-001.reichenau.nimius-wip.de => tun-001.reichenau.ddev.local.
     * Modifying domain: tun-001.allensbach.nimius-wip.de => tun-001.allensbach.ddev.local.
     *
     * @param string|null $pattern Optional: Regex pattern: If none is provided, config value is used.
     * @param string|null $replace Optional: Replacement string: If none is provided, config value is used.
     */
    public function migrateCommand(string $pattern = null, string $replace = null): void
    {
        $pattern = $pattern ?? $this->configuration['pattern'];
        if (empty($pattern)) {
            $this->output->outputLine('No pattern configured. Exiting.');
            return;
        }
        if ($pattern{0} !== $pattern{-1}) {
            $this->outputLine(
                '<em>First and last characters of replacement pattern are not equal.'
                . ' Assuming you forgot to specify a regex and converting it.</em>'
            );
            $pattern = '/' . preg_quote($pattern, '/') . '/';
            $this->outputLine(sprintf('Replacement pattern is now `%s`', $pattern));
        }

        $replace = $replace ?? $this->configuration['replace'];

        $modified = 0;

        /** @var Domain $domain */
        foreach ($this->domainRepository->findAll() as $domain) {
            $originalHostname = $domain->getHostname();
            /** @var string $hostname */
            $hostname = preg_replace($pattern, $replace, $originalHostname);
            if ($originalHostname !== $hostname) {
                $this->output->outputLine(sprintf('Modifying domain: %s => %s.', $originalHostname, $hostname));
                $domain->setHostname($hostname);
                $this->domainRepository->update($domain);
                $modified++;
            }
        }

        $this->output->outputLine(sprintf('Modified %d domains.', $modified));
    }
}
