<?php

declare(strict_types=1);

namespace App\Framework\Mcp\Core\ValueObjects;

/**
 * Execution Task Value Object
 *
 * Represents a single task to be executed in the concurrent execution system.
 */
final readonly class ExecutionTask
{
    public function __construct(
        private string $id,
        private string $toolName,
        private string $methodName,
        private array $parameters = [],
        private int $priority = 0,
        private int $estimatedMemory = 25 * 1024 * 1024, // 25MB default
        private float $estimatedTime = 3.0, // 3 seconds default
        private CacheStrategy $cacheStrategy = CacheStrategy::ADAPTIVE,
        private OptimizationStrategy $optimizationStrategy = OptimizationStrategy::BALANCED,
        private OutputFormat $outputFormat = OutputFormat::ARRAY,
        private bool $shouldOptimize = true,
        private bool $dependsOnPrevious = false,
        private array $metadata = []
    ) {
    }

    public function getId(): string
    {
        return $this->id;
    }

    public function getToolName(): string
    {
        return $this->toolName;
    }

    public function getMethodName(): string
    {
        return $this->methodName;
    }

    public function getParameters(): array
    {
        return $this->parameters;
    }

    public function getPriority(): int
    {
        return $this->priority;
    }

    public function getEstimatedMemory(): int
    {
        return $this->estimatedMemory;
    }

    public function getEstimatedTime(): float
    {
        return $this->estimatedTime;
    }

    public function getCacheStrategy(): CacheStrategy
    {
        return $this->cacheStrategy;
    }

    public function getOptimizationStrategy(): OptimizationStrategy
    {
        return $this->optimizationStrategy;
    }

    public function getOutputFormat(): OutputFormat
    {
        return $this->outputFormat;
    }

    public function shouldOptimize(): bool
    {
        return $this->shouldOptimize;
    }

    public function dependsOnPrevious(): bool
    {
        return $this->dependsOnPrevious;
    }

    public function getMetadata(): array
    {
        return $this->metadata;
    }

    public function withPreviousResult(mixed $result): self
    {
        $newParameters = array_merge($this->parameters, ['__previous_result' => $result]);

        return new self(
            id: $this->id,
            toolName: $this->toolName,
            methodName: $this->methodName,
            parameters: $newParameters,
            priority: $this->priority,
            estimatedMemory: $this->estimatedMemory,
            estimatedTime: $this->estimatedTime,
            cacheStrategy: $this->cacheStrategy,
            optimizationStrategy: $this->optimizationStrategy,
            outputFormat: $this->outputFormat,
            shouldOptimize: $this->shouldOptimize,
            dependsOnPrevious: $this->dependsOnPrevious,
            metadata: $this->metadata
        );
    }

    public static function create(
        string $toolName,
        string $methodName,
        array $parameters = []
    ): self {
        return new self(
            id: uniqid($toolName . '_' . $methodName . '_', true),
            toolName: $toolName,
            methodName: $methodName,
            parameters: $parameters
        );
    }

    public static function highPriority(
        string $toolName,
        string $methodName,
        array $parameters = []
    ): self {
        return new self(
            id: uniqid($toolName . '_' . $methodName . '_hp_', true),
            toolName: $toolName,
            methodName: $methodName,
            parameters: $parameters,
            priority: 100
        );
    }

    public static function lowResource(
        string $toolName,
        string $methodName,
        array $parameters = []
    ): self {
        return new self(
            id: uniqid($toolName . '_' . $methodName . '_lr_', true),
            toolName: $toolName,
            methodName: $methodName,
            parameters: $parameters,
            estimatedMemory: 5 * 1024 * 1024, // 5MB
            estimatedTime: 1.0 // 1 second
        );
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'tool_name' => $this->toolName,
            'method_name' => $this->methodName,
            'parameters' => $this->parameters,
            'priority' => $this->priority,
            'estimated_memory' => $this->estimatedMemory,
            'estimated_time' => $this->estimatedTime,
            'cache_strategy' => $this->cacheStrategy->value,
            'optimization_strategy' => $this->optimizationStrategy->value,
            'output_format' => $this->outputFormat->value,
            'should_optimize' => $this->shouldOptimize,
            'depends_on_previous' => $this->dependsOnPrevious,
            'metadata' => $this->metadata,
        ];
    }
}
