<?php

namespace MintyPHP\Tests\Console;

use MintyPHP\Console\Commands\Make\ModuleCommand;
use PHPUnit\Framework\TestCase;

final class MakeModuleCommandTest extends TestCase
{
    private string $modulesDir;

    /** @var list<string> Module IDs to clean up */
    private array $cleanup = [];

    protected function setUp(): void
    {
        $this->modulesDir = dirname(__DIR__, 2) . '/modules';
    }

    protected function tearDown(): void
    {
        foreach ($this->cleanup as $id) {
            $this->removeDir($this->modulesDir . '/' . $id);
        }
    }

    public function testSimpleFlagGeneratesMinimalManifest(): void
    {
        $id = 'ztest-simple-scaffold';
        $this->cleanup[] = $id;

        $command = new ModuleCommand();
        $exitCode = @$command->execute([$id], ['simple' => true]);

        self::assertSame(0, $exitCode);

        $manifestFile = $this->modulesDir . '/' . $id . '/module.php';
        self::assertFileExists($manifestFile);

        $manifest = require $manifestFile;
        self::assertIsArray($manifest);

        // Essential fields present
        self::assertSame($id, $manifest['id']);
        self::assertSame('0.1.0', $manifest['version']);
        self::assertArrayHasKey('container_registrars', $manifest);
        self::assertArrayHasKey('authorization_policies', $manifest);

        // Verbose fields NOT present in simple mode
        self::assertArrayNotHasKey('routes', $manifest);
        self::assertArrayNotHasKey('ui_slots', $manifest);
        self::assertArrayNotHasKey('permissions', $manifest);
        self::assertArrayNotHasKey('scheduler_jobs', $manifest);
        self::assertArrayNotHasKey('event_listeners', $manifest);
    }

    public function testDefaultModeGeneratesFullManifest(): void
    {
        $id = 'ztest-full-scaffold';
        $this->cleanup[] = $id;

        $command = new ModuleCommand();
        $exitCode = @$command->execute([$id], []);

        self::assertSame(0, $exitCode);

        $manifestFile = $this->modulesDir . '/' . $id . '/module.php';
        $manifest = require $manifestFile;

        // Full mode includes all fields
        self::assertArrayHasKey('routes', $manifest);
        self::assertArrayHasKey('ui_slots', $manifest);
        self::assertArrayHasKey('permissions', $manifest);
        self::assertArrayHasKey('event_listeners', $manifest);
    }

    public function testSimpleManifestIsValidForManifestLoader(): void
    {
        $id = 'ztest-simple-valid';
        $this->cleanup[] = $id;

        $command = new ModuleCommand();
        $exitCode = @$command->execute([$id], ['simple' => true]);
        self::assertSame(0, $exitCode);

        $manifest = \MintyPHP\App\Module\ModuleManifestLoader::loadFromDisk($this->modulesDir, $id);
        self::assertSame($id, $manifest->id);
        self::assertSame('0.1.0', $manifest->version);
    }

    private function removeDir(string $dir): void
    {
        if (!is_dir($dir)) {
            return;
        }
        $items = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
            \RecursiveIteratorIterator::CHILD_FIRST
        );
        foreach ($items as $item) {
            if ($item->isDir()) {
                rmdir($item->getPathname());
            } else {
                unlink($item->getPathname());
            }
        }
        rmdir($dir);
    }
}
