<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Providers;

use PrettyLinks\GroundLevel\Container\Container;
use PrettyLinks\GroundLevel\Container\ServiceProvider;
use PrettyLinks\Pro\Expiration\ExpirationChecker;
use PrettyLinks\Pro\PrettyBar\BarRenderer;
use PrettyLinks\Pro\Qr\QrService;
use PrettyLinks\Pro\RedirectTypes\CloakRenderer;
use PrettyLinks\Pro\RedirectTypes\JavascriptRenderer;
use PrettyLinks\Pro\RedirectTypes\MetaRefreshRenderer;
use PrettyLinks\Pro\RedirectTypes\PixelRenderer;
use PrettyLinks\Pro\Rotation\RotationService;
use PrettyLinks\Pro\Rotation\RotationsRepository;
use PrettyLinks\Pro\Targeting\Evaluator as TargetingEvaluator;
use PrettyLinks\Repositories\LinkMetas;

/**
 * Redirect-time behavior: the renderers for each non-301/302 redirect type
 * (Pretty Bar, cloak, pixel, meta-refresh, JavaScript, QR), plus the
 * rotation, targeting, and expiration services that decide which target a
 * link resolves to.
 */
class RedirectServiceProvider extends ServiceProvider
{
    /**
     * Service definitions registered with the container.
     *
     * @return array<int, array{id: string, lifecycle: string, closure: \Closure|null, eager: bool}>
     */
    public function services(): array
    {
        return [
            $this->service(
                BarRenderer::class,
                self::SINGLETON,
                static function (Container $c): BarRenderer {
                    return new BarRenderer($c->get(LinkMetas::class));
                }
            ),

            $this->service(
                CloakRenderer::class,
                self::SINGLETON,
                static function (): CloakRenderer {
                    return new CloakRenderer();
                }
            ),

            $this->service(
                PixelRenderer::class,
                self::SINGLETON,
                static function (): PixelRenderer {
                    return new PixelRenderer();
                }
            ),

            $this->service(
                MetaRefreshRenderer::class,
                self::SINGLETON,
                static function (Container $c): MetaRefreshRenderer {
                    return new MetaRefreshRenderer($c->get(LinkMetas::class));
                }
            ),

            $this->service(
                JavascriptRenderer::class,
                self::SINGLETON,
                static function (Container $c): JavascriptRenderer {
                    return new JavascriptRenderer($c->get(LinkMetas::class));
                }
            ),

            $this->service(
                QrService::class,
                self::SINGLETON,
                static function (): QrService {
                    return new QrService();
                }
            ),

            $this->service(
                RotationService::class,
                self::SINGLETON,
                static function (): RotationService {
                    return new RotationService();
                }
            ),

            $this->service(
                RotationsRepository::class,
                self::SINGLETON,
                static function (): RotationsRepository {
                    return new RotationsRepository();
                }
            ),

            $this->service(
                TargetingEvaluator::class,
                self::SINGLETON,
                static function (): TargetingEvaluator {
                    return new TargetingEvaluator();
                }
            ),

            $this->service(
                ExpirationChecker::class,
                self::SINGLETON,
                static function (): ExpirationChecker {
                    return new ExpirationChecker();
                }
            ),
        ];
    }
}
