<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

/**
 * The `modules` table stores each module's fully-qualified class name, so the io 6
 * namespace normalisation is a data change as well as a code change: without this
 * every registered module fails to resolve at boot and no hooks are registered.
 *
 * The two install modules were removed in io 6 and their rows go with them.
 */
final class RenameModuleClassesForIo6 extends AbstractMigration
{
    private const array RENAMES = [
        'apexl\Io\modules\admin\adminModule' => 'Apexl\Io\Admin\AdminModule',
        'apexl\Io\modules\adminDisplay\adminDisplayModule' => 'Apexl\Io\Admin\Display\AdminDisplayModule',
        'apexl\Io\modules\authentication\authenticationModule' => 'Apexl\Io\Modules\AuthenticationModule',
        'apexl\Io\modules\component\componentModule' => 'Apexl\Io\Component\ComponentModule',
        'apexl\Io\modules\cron\cronModule' => 'Apexl\Io\Cron\CronModule',
        'apexl\Io\modules\display\displayModule' => 'Apexl\Io\Display\DisplayModule',
        'apexl\Io\modules\file\fileModule' => 'Apexl\Io\File\FileModule',
        'apexl\Io\modules\formbuilder\formbuilderModule' => 'Apexl\Io\FormBuilder\FormBuilderModule',
        'apexl\Io\modules\jobs\jobsModule' => 'Apexl\Io\Jobs\JobsModule',
        'apexl\Io\modules\logger\loggerModule' => 'Apexl\Io\Modules\LoggerModule',
        'apexl\Io\modules\menu\menuModule' => 'Apexl\Io\Menu\MenuModule',
        'apexl\Io\modules\mirror\mirrorModule' => 'Apexl\Io\Mirror\MirrorModule',
        'apexl\Io\modules\notifier\notifierModule' => 'Apexl\Io\Notifier\NotifierModule',
        'apexl\Io\modules\system\systemModule' => 'Apexl\Io\Modules\SystemModule',
        'apexl\Io\modules\tabulator\tabulatorModule' => 'Apexl\Io\Tabulator\TabulatorModule',
        'apexl\Io\modules\user\userModule' => 'Apexl\Io\User\UserModule',
        'apexl\Io\modules\userDisplay\userDisplayModule' => 'Apexl\Io\User\Display\UserDisplayModule',
        'apexl\Io\modules\validation\validationModule' => 'Apexl\Io\Validation\ValidationModule',
    ];

    private const array REMOVED = [
        'apexl\Io\modules\install\installModule',
        'apexl\Io\modules\installDisplay\installDisplayModule',
    ];

    public function up(): void
    {
        foreach (self::RENAMES as $old => $new) {
            $this->execute('UPDATE modules SET module = ? WHERE module = ?', [$new, $old]);
        }

        foreach (self::REMOVED as $module) {
            $this->execute('DELETE FROM modules WHERE module = ?', [$module]);
        }
    }

    public function down(): void
    {
        foreach (self::RENAMES as $old => $new) {
            $this->execute('UPDATE modules SET module = ? WHERE module = ?', [$old, $new]);
        }

        // The install modules are gone from the codebase; there is nothing to restore.
    }
}
