<?php

namespace Tests\Support;

use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\File;

trait ManagesTestKeys
{
    protected static string $testKeyDirectory;

    /**
     * Set up test keys before the test suite runs.
     */
    public static function setUpTestKeys(): void
    {
        // Use Laravel's base path directly to avoid storage_path() issues in beforeAll
        static::$testKeyDirectory = base_path('storage/testing/oauth');
        
        // Clean up any existing test keys
        if (File::exists(static::$testKeyDirectory)) {
            File::deleteDirectory(static::$testKeyDirectory);
        }

        // Generate fresh test keys
        Artisan::call('app:generate-keys', ['--path' => static::$testKeyDirectory]);
    }

    /**
     * Clean up test keys after the test suite runs.
     */
    public static function tearDownTestKeys(): void
    {
        if (isset(static::$testKeyDirectory) && File::exists(static::$testKeyDirectory)) {
            File::deleteDirectory(static::$testKeyDirectory);
        }
    }

    /**
     * Get the test key directory path.
     */
    protected function getTestKeyDirectory(): string
    {
        return static::$testKeyDirectory ?? base_path('storage/testing/oauth');
    }

    /**
     * Get the test private key path.
     */
    protected function getTestPrivateKeyPath(): string
    {
        return $this->getTestKeyDirectory() . '/private.pem';
    }

    /**
     * Get the test public key path.
     */
    protected function getTestPublicKeyPath(): string
    {
        return $this->getTestKeyDirectory() . '/public.pem';
    }

    /**
     * Ensure test keys exist for the current test.
     */
    protected function ensureTestKeysExist(): void
    {
        $keyDir = $this->getTestKeyDirectory();
        $privateKeyPath = $this->getTestPrivateKeyPath();
        $publicKeyPath = $this->getTestPublicKeyPath();

        // Only generate if keys don't exist
        if (!File::exists($privateKeyPath) || !File::exists($publicKeyPath)) {
            // Create directory if it doesn't exist
            if (!File::exists($keyDir)) {
                File::makeDirectory($keyDir, 0700, true);
            }

            // Generate test keys
            $keyPair = openssl_pkey_new([
                'digest_alg' => 'sha256',
                'private_key_bits' => 2048,
                'private_key_type' => OPENSSL_KEYTYPE_RSA,
            ]);

            openssl_pkey_export($keyPair, $privateKey);
            $publicKey = openssl_pkey_get_details($keyPair)['key'];

            File::put($privateKeyPath, $privateKey);
            File::put($publicKeyPath, $publicKey);

            // Set proper permissions
            chmod($privateKeyPath, 0600);
            chmod($publicKeyPath, 0644);
        }
    }
}