<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\DI\Definition;

use PpPhp\Core\Platform\DI\Contracts\ContainerInterface;
use PpPhp\Core\Platform\DI\Contracts\ResolverInterface;
use PpPhp\Core\Platform\DI\Metadata\DefinitionType;
use PpPhp\Core\Platform\DI\Metadata\Lifetime;

/**
 * Legacy-safe definition shim.
 *
 * R0100.4A v3 finalizes the DI definition model. This class remains only so
 * older classmaps and references can load safely. New code should use
 * ClassDefinition, FactoryDefinition, InstanceDefinition, AliasDefinition, or
 * ValueDefinition directly.
 */
final class ServiceDefinition extends AbstractDefinition
{
    private mixed $target;

    public function __construct(string $id, mixed $target = null, string $lifetime = Lifetime::TRANSIENT)
    {
        parent::__construct($id, $lifetime);
        $this->target = $target ?? $id;
    }

    public function type(): string
    {
        return DefinitionType::SYNTHETIC_SERVICE;
    }

    public function target(): mixed
    {
        return $this->target;
    }

    public function resolve(ContainerInterface $container, ResolverInterface $resolver): mixed
    {
        if (is_string($this->target) && class_exists($this->target)) {
            return $resolver->buildClass($this->target, $container);
        }

        if (is_object($this->target)) {
            return $this->target;
        }

        if (is_callable($this->target)) {
            return ($this->target)($container);
        }

        return $this->target;
    }

    public function toArray(): array
    {
        return $this->baseArray() + [
            'legacy' => true,
            'targetType' => gettype($this->target),
            'target' => is_scalar($this->target) || $this->target === null ? $this->target : (
                is_object($this->target) ? $this->target::class : '[non-exportable]'
            ),
        ];
    }
}
