<?php

declare(strict_types=1);

namespace App\Framework\Database\Migration\Exception;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;

final class MemoryThresholdExceededException extends FrameworkException
{
    public static function forMigration(
        string $migrationVersion,
        Percentage $currentUsage,
        Percentage $threshold,
        Byte $currentMemory,
        Byte $memoryLimit
    ): self {
        return self::create(
            ErrorCode::PERF_MEMORY_LIMIT_EXCEEDED,
            "Memory threshold exceeded during migration {$migrationVersion}: {$currentUsage->format(1)}% (threshold: {$threshold->format(1)}%)"
        )->withData([
            'migration_version' => $migrationVersion,
            'current_usage_percentage' => $currentUsage->getValue(),
            'threshold_percentage' => $threshold->getValue(),
            'current_memory' => $currentMemory->toHumanReadable(),
            'memory_limit' => $memoryLimit->toHumanReadable(),
            'available_memory' => $memoryLimit->subtract($currentMemory)->toHumanReadable(),
        ])->withMetadata([
            'category' => 'memory',
            'severity' => 'high',
            'action_required' => 'Consider increasing memory limit or running migrations in smaller batches',
        ]);
    }

    public static function batchAborted(
        Percentage $currentUsage,
        Percentage $abortThreshold,
        Byte $currentMemory,
        Byte $memoryLimit,
        int $completedMigrations,
        int $totalMigrations
    ): self {
        return self::create(
            ErrorCode::PERF_MEMORY_LIMIT_EXCEEDED,
            "Migration batch aborted due to critical memory usage: {$currentUsage->format(1)}% (abort threshold: {$abortThreshold->format(1)}%)"
        )->withData([
            'current_usage_percentage' => $currentUsage->getValue(),
            'abort_threshold_percentage' => $abortThreshold->getValue(),
            'current_memory' => $currentMemory->toHumanReadable(),
            'memory_limit' => $memoryLimit->toHumanReadable(),
            'completed_migrations' => $completedMigrations,
            'total_migrations' => $totalMigrations,
            'remaining_migrations' => $totalMigrations - $completedMigrations,
        ])->withMetadata([
            'category' => 'memory',
            'severity' => 'critical',
            'action_required' => 'Increase memory limit or run remaining migrations separately',
        ]);
    }
}
