<?php

use App\Contracts\Hardening\WriteGateInterface;
use App\Exceptions\Hardening\ProviderAccessHardeningRequired;
use App\Models\ManagedEnvironment;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function () {
    config()->set('tenantpilot.hardening.intune_write_gate.enabled', true);
    config()->set('tenantpilot.hardening.intune_write_gate.freshness_threshold_hours', 24);
});

test('gate blocks when rbac_status is degraded', function () {
    $tenant = ManagedEnvironment::factory()->create([
        'rbac_status' => 'degraded',
        'rbac_last_checked_at' => now(),
    ]);

    $gate = app(WriteGateInterface::class);

    try {
        $gate->evaluate($tenant, 'restore.execute');
        $this->fail('Expected ProviderAccessHardeningRequired to be thrown');
    } catch (ProviderAccessHardeningRequired $e) {
        expect($e->reasonCode)->toBe('intune_rbac.unhealthy')
            ->and($e->tenantId)->toBe((int) $tenant->getKey());
    }
});

test('gate blocks when rbac_status is failed', function () {
    $tenant = ManagedEnvironment::factory()->create([
        'rbac_status' => 'failed',
        'rbac_last_checked_at' => now(),
    ]);

    $gate = app(WriteGateInterface::class);

    try {
        $gate->evaluate($tenant, 'restore.execute');
        $this->fail('Expected ProviderAccessHardeningRequired to be thrown');
    } catch (ProviderAccessHardeningRequired $e) {
        expect($e->reasonCode)->toBe('intune_rbac.unhealthy');
    }
});

test('gate blocks when rbac_status is error', function () {
    $tenant = ManagedEnvironment::factory()->create([
        'rbac_status' => 'error',
        'rbac_last_checked_at' => now(),
    ]);

    $gate = app(WriteGateInterface::class);

    try {
        $gate->evaluate($tenant, 'restore.execute');
        $this->fail('Expected ProviderAccessHardeningRequired to be thrown');
    } catch (ProviderAccessHardeningRequired $e) {
        expect($e->reasonCode)->toBe('intune_rbac.unhealthy');
    }
});

test('wouldBlock returns true for all unhealthy statuses', function (string $status) {
    $tenant = ManagedEnvironment::factory()->create([
        'rbac_status' => $status,
        'rbac_last_checked_at' => now(),
    ]);

    expect(app(WriteGateInterface::class)->wouldBlock($tenant))->toBeTrue();
})->with(['degraded', 'failed', 'error', 'missing', 'partial']);
