<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Laravel\Fortify\Features;
use RuntimeException;

abstract class TestCase extends BaseTestCase
{
    /**
     * Refuse to run against anything but the in-memory SQLite database.
     *
     * RefreshDatabase calls migrate:fresh, so a test run pointed at a real
     * database destroys it. phpunit.xml pins sqlite/:memory:, but PHPUnit's
     * `force="true"` overwrites only getenv()/$_ENV — not $_SERVER, which
     * Laravel's Env::get() also reads. An ambient DB_CONNECTION therefore
     * still leaks through. This is the backstop.
     *
     * Set ALLOW_NON_SQLITE_TESTS=1 to opt out deliberately.
     */
    protected function refreshApplication(): void
    {
        parent::refreshApplication();

        // Runs before setUpTraits(), i.e. before RefreshDatabase::migrate:fresh.
        if (env('ALLOW_NON_SQLITE_TESTS')) {
            return;
        }

        $connection = config('database.default');
        $database = config("database.connections.{$connection}.database");

        if ($connection !== 'sqlite' || $database !== ':memory:') {
            throw new RuntimeException(sprintf(
                'Refusing to run tests against [%s/%s]. RefreshDatabase would wipe it. '
                    .'Unset any DB_CONNECTION/DB_DATABASE in your environment, or set '
                    .'ALLOW_NON_SQLITE_TESTS=1 to override.',
                $connection,
                (string) $database,
            ));
        }
    }

    protected function skipUnlessFortifyHas(string $feature, ?string $message = null): void
    {
        if (! Features::enabled($feature)) {
            $this->markTestSkipped($message ?? "Fortify feature [{$feature}] is not enabled.");
        }
    }
}
