<?php

declare(strict_types=1);

use App\Models\OperationRun;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Feature\Baselines\Support\BaselineSubjectResolutionFixtures;

uses(RefreshDatabase::class);

it('reports legacy compare and capture runs in dry-run mode without deleting them', function (): void {
    [, $tenant] = createUserWithTenant(role: 'owner');

    $legacyCompare = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => [
            'baseline_compare' => [
                'evidence_gaps' => [
                    'count' => 1,
                    'by_reason' => ['policy_not_found' => 1],
                    'subjects' => [
                        'policy_not_found' => [
                            'deviceConfiguration|legacy-policy-gap',
                        ],
                    ],
                ],
            ],
        ],
    ]);

    $legacyCapture = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCapture->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => [
            'baseline_capture' => [
                'gaps' => [
                    'count' => 1,
                    'by_reason' => ['policy_not_found' => 1],
                    'subjects' => [
                        'policy_not_found' => [
                            'deviceConfiguration|legacy-capture-gap',
                        ],
                    ],
                ],
            ],
        ],
    ]);

    $structuredCompare = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => BaselineSubjectResolutionFixtures::compareContext([
            BaselineSubjectResolutionFixtures::structuredGap(),
        ]),
    ]);

    expect($legacyCompare->hasLegacyBaselineGapPayload())->toBeTrue()
        ->and($legacyCapture->hasLegacyBaselineGapPayload())->toBeTrue()
        ->and($structuredCompare->hasStructuredBaselineGapPayload())->toBeTrue()
        ->and($structuredCompare->hasLegacyBaselineGapPayload())->toBeFalse();

    $this->artisan('tenantpilot:baselines:purge-legacy-gap-runs')
        ->expectsOutputToContain('Dry run: matched 2 legacy baseline run(s). Re-run with --force to delete them.')
        ->assertSuccessful();

    expect(OperationRun::query()->whereKey($legacyCompare->getKey())->exists())->toBeTrue()
        ->and(OperationRun::query()->whereKey($legacyCapture->getKey())->exists())->toBeTrue()
        ->and(OperationRun::query()->whereKey($structuredCompare->getKey())->exists())->toBeTrue();
});

it('deletes only legacy baseline gap runs when forced', function (): void {
    [, $tenant] = createUserWithTenant(role: 'owner');

    $legacyCompare = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => [
            'baseline_compare' => [
                'evidence_gaps' => [
                    'count' => 1,
                    'by_reason' => ['policy_not_found' => 1],
                    'subjects' => [
                        'policy_not_found' => [
                            'deviceConfiguration|legacy-policy-gap',
                        ],
                    ],
                ],
            ],
        ],
    ]);

    $structuredCompare = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => BaselineSubjectResolutionFixtures::compareContext([
            BaselineSubjectResolutionFixtures::structuredGap(),
        ]),
    ]);

    $structuredCapture = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => OperationRunType::BaselineCapture->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'context' => BaselineSubjectResolutionFixtures::captureContext([
            BaselineSubjectResolutionFixtures::structuredGap(),
        ]),
    ]);

    $this->artisan('tenantpilot:baselines:purge-legacy-gap-runs', ['--force' => true])
        ->expectsOutputToContain('Deleted 1 legacy baseline run(s).')
        ->assertSuccessful();

    expect(OperationRun::query()->whereKey($legacyCompare->getKey())->exists())->toBeFalse()
        ->and(OperationRun::query()->whereKey($structuredCompare->getKey())->exists())->toBeTrue()
        ->and(OperationRun::query()->whereKey($structuredCapture->getKey())->exists())->toBeTrue();
});
