<?php

declare(strict_types=1);

namespace App\Framework\Discovery\ValueObjects;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Filesystem\ValueObjects\FilePath;

/**
 * Immutable value object for interface implementation mappings
 * Replaces simple arrays with memory-efficient typed structure
 */
final readonly class InterfaceMapping
{
    public function __construct(
        public ClassName $interface,
        public ClassName $implementation,
        public FilePath $file
    ) {
    }

    public static function create(
        string $interface,
        string $implementation,
        string $file
    ): self {
        return new self(
            interface: ClassName::create($interface),
            implementation: ClassName::create($implementation),
            file: FilePath::create($file)
        );
    }

    /**
     * Get unique identifier for deduplication
     */
    public function getUniqueId(): string
    {
        return $this->interface->getFullyQualified() . '::' . $this->implementation->getFullyQualified();
    }

    /**
     * Check if this mapping is the same as another
     */
    public function isSameAs(self $other): bool
    {
        return $this->interface->equals($other->interface) &&
               $this->implementation->equals($other->implementation);
    }

    /**
     * Check if this implements the given interface
     */
    public function implementsInterface(ClassName $interface): bool
    {
        return $this->interface->equals($interface);
    }

    /**
     * Get memory footprint estimate
     */
    public function getMemoryFootprint(): Byte
    {
        $bytes = strlen($this->interface->getFullyQualified()) +
                 strlen($this->implementation->getFullyQualified()) +
                 strlen($this->file->toString());

        return Byte::fromBytes($bytes);
    }

    /**
     * Serialize to array for cache storage
     */
    public function toArray(): array
    {
        return [
            'interface' => $this->interface->getFullyQualified(),
            'implementation' => $this->implementation->getFullyQualified(),
            'file' => $this->file->toString(),
        ];
    }

    /**
     * Create from array for cache deserialization
     */
    public static function fromArray(array $data): self
    {
        return new self(
            interface: ClassName::create($data['interface']),
            implementation: ClassName::create($data['implementation']),
            file: FilePath::create($data['file'])
        );
    }
}
