<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Providers;

use PrettyLinks\GroundLevel\Container\Container;
use PrettyLinks\GroundLevel\Container\ServiceProvider;
use PrettyLinks\Pro\Options\Store as OptionsStore;
use PrettyLinks\Pro\Replacements\CacheInvalidator;
use PrettyLinks\Pro\Replacements\Disclosures;
use PrettyLinks\Pro\Replacements\KeywordAddLog;
use PrettyLinks\Pro\Replacements\KeywordEngine;
use PrettyLinks\Pro\Replacements\KeywordIndexer;
use PrettyLinks\Pro\Replacements\KeywordRepository;
use PrettyLinks\Pro\Replacements\PostUrlCache;
use PrettyLinks\Pro\Replacements\PostUrlCacheInvalidator;
use PrettyLinks\Pro\Replacements\UrlReplacer;
use PrettyLinks\Pro\Tools\DuplicateKeywords;

/**
 * Keyword-replacement subsystem: the keyword repository and its add-log,
 * the indexer + cache invalidation, disclosures, the replacement engine,
 * the post-URL cache, and the duplicate-keyword tool. All keyword-domain
 * services live here.
 */
class ReplacementsServiceProvider 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(
                KeywordRepository::class,
                self::SINGLETON,
                static function (): KeywordRepository {
                    return new KeywordRepository();
                }
            ),

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

            $this->service(
                CacheInvalidator::class,
                self::SINGLETON,
                static function (Container $c): CacheInvalidator {
                    return new CacheInvalidator(
                        $c->get(KeywordIndexer::class),
                        $c->get(KeywordAddLog::class),
                        $c->get(KeywordRepository::class)
                    );
                }
            ),

            $this->service(
                KeywordIndexer::class,
                self::SINGLETON,
                static function (Container $c): KeywordIndexer {
                    return new KeywordIndexer(
                        $c->get(KeywordRepository::class),
                        $c->get(OptionsStore::class),
                        $c->get(KeywordAddLog::class)
                    );
                }
            ),

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

            $this->service(
                KeywordEngine::class,
                self::SINGLETON,
                static function (Container $c): KeywordEngine {
                    return new KeywordEngine(
                        $c->get(KeywordRepository::class),
                        $c->get(KeywordIndexer::class),
                        $c->get(OptionsStore::class),
                        $c->get(Disclosures::class)
                    );
                }
            ),

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

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

            $this->service(
                UrlReplacer::class,
                self::SINGLETON,
                static function (Container $c): UrlReplacer {
                    return new UrlReplacer(
                        $c->get(OptionsStore::class),
                        $c->get(Disclosures::class),
                        $c->get(PostUrlCache::class)
                    );
                }
            ),

            $this->service(
                DuplicateKeywords::class,
                self::SINGLETON,
                static function (Container $c): DuplicateKeywords {
                    return new DuplicateKeywords(
                        $c->get(KeywordRepository::class),
                        $c->get(CacheInvalidator::class)
                    );
                }
            ),
        ];
    }
}
