<?php

declare(strict_types=1);

namespace App\Framework\DI\Dependency;

use App\Framework\Core\ValueObjects\ClassName;

/**
 * Represents a cached constructor parameter with its dependency information
 */
final readonly class ConstructorCacheEntry
{
    private function __construct(
        public ClassName $className,
        public ParameterCacheCollection $parameters
    ) {
    }

    /**
     * Create cache entry for a class with no constructor parameters
     */
    public static function empty(ClassName $className): self
    {
        return new self($className, ParameterCacheCollection::empty());
    }

    /**
     * Create cache entry from resolved dependencies
     * @param array<array<string, mixed>> $cacheInfo
     */
    public static function fromCacheInfo(ClassName $className, array $cacheInfo): self
    {
        return new self($className, ParameterCacheCollection::fromArray($cacheInfo));
    }

    /**
     * Create cache entry from ParameterCacheInfo objects
     */
    public static function fromParameters(ClassName $className, ParameterCacheInfo ...$parameters): self
    {
        return new self($className, ParameterCacheCollection::from(...$parameters));
    }

    /**
     * Check if constructor has parameters
     */
    public function hasParameters(): bool
    {
        return ! $this->parameters->isEmpty();
    }

    /**
     * Get number of parameters
     */
    public function getParameterCount(): int
    {
        return $this->parameters->count();
    }

    /**
     * Get parameter cache info at specific position
     */
    public function getParameter(int $position): ?ParameterCacheInfo
    {
        return $this->parameters->get($position);
    }

    /**
     * Get parameter cache collection
     */
    public function getParameters(): ParameterCacheCollection
    {
        return $this->parameters;
    }

    /**
     * Get parameters as legacy array format (for backward compatibility)
     * @return array<array<string, mixed>>
     */
    public function getParametersAsArray(): array
    {
        return $this->parameters->toLegacyArray();
    }

    /**
     * Get dependency types used in this constructor
     * @return array<DependencyType>
     */
    public function getDependencyTypes(): array
    {
        return $this->parameters->getDependencyTypes();
    }

    /**
     * Check if constructor uses specific dependency type
     */
    public function usesDependencyType(DependencyType $dependencyType): bool
    {
        return $this->parameters->usesDependencyType($dependencyType);
    }

    /**
     * Get all class dependencies referenced in this constructor
     * @return array<ClassName>
     */
    public function getClassDependencies(): array
    {
        return $this->parameters->getClassDependencies();
    }

    /**
     * Check if constructor depends on specific class
     */
    public function dependsOn(ClassName $className): bool
    {
        return $this->parameters->dependsOn($className);
    }
}
