<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\DI;

use PpPhp\Core\Platform\DI\Contracts\DefinitionInterface;
use PpPhp\Core\Platform\DI\Contracts\RegistrationInterface;
use PpPhp\Core\Platform\DI\Metadata\Lifetime;
use PpPhp\Core\Platform\DI\Metadata\Visibility;
use PpPhp\Core\Platform\DI\Repository\AliasRepository;
use PpPhp\Core\Platform\DI\Repository\TagRepository;

final class RegistrationBuilder implements RegistrationInterface
{
    public function __construct(
        private DefinitionInterface $definition,
        private AliasRepository $aliases,
        private TagRepository $tags
    ) {}

    public function definition(): DefinitionInterface { return $this->definition; }
    public function singleton(): self { $this->definition->withLifetime(Lifetime::SINGLETON); return $this; }
    public function scoped(): self { $this->definition->withLifetime(Lifetime::SCOPED); return $this; }
    public function prototype(): self { $this->definition->withLifetime(Lifetime::PROTOTYPE); return $this; }
    public function transient(): self { $this->definition->withLifetime(Lifetime::TRANSIENT); return $this; }
    public function public(): self { $this->definition->withVisibility(Visibility::PUBLIC); return $this; }
    public function private(): self { $this->definition->withVisibility(Visibility::PRIVATE); return $this; }
    public function lazy(bool $lazy = true): self { $this->definition->withLazy($lazy); return $this; }

    public function tag(string $tag, array $attributes = []): self
    {
        $this->definition->withTag($tag, $attributes);
        $this->tags->add($tag, $this->definition->id(), $attributes);
        return $this;
    }

    public function alias(string $alias): self
    {
        $this->definition->withAlias($alias);
        $this->aliases->add($alias, $this->definition->id());
        return $this;
    }

    public function metadata(string $key, mixed $value): self
    {
        $this->definition->withMetadata($key, $value);
        return $this;
    }
}
