<?php

declare(strict_types=1);

namespace App\Framework\Database;

/**
 * IdentityMap is a pattern implementation that provides a way to manage
 * and track instances of entities by their unique identifiers within a single context.
 * It helps prevent duplicate instances of the same entity in memory.
 */
final class IdentityMap
{
    private array $entities = [];

    public function get(string $entityClass, mixed $id): ?object
    {
        $key = $this->createKey($entityClass, $id);
        return $this->entities[$key] ?? null;
    }

    public function set(string $entityClass, mixed $id, object $entity): void
    {
        $key = $this->createKey($entityClass, $id);
        $this->entities[$key] = $entity;
    }

    public function has(string $entityClass, mixed $id): bool
    {
        $key = $this->createKey($entityClass, $id);
        return isset($this->entities[$key]);
    }

    public function remove(string $entityClass, mixed $id): void
    {
        $key = $this->createKey($entityClass, $id);
        unset($this->entities[$key]);
    }

    public function clear(): void
    {
        $this->entities = [];
    }

    public function getStats(): array
    {
        return [
            'total_entities' => count($this->entities),
            'entity_types' => array_count_values(
                array_map(fn($key) => explode('#', $key)[0], array_keys($this->entities))
            )
        ];
    }

    private function createKey(string $entityClass, mixed $id): string
    {
        return $entityClass . '#' . $id;
    }
}
