<?php

use function DI\autowire, DI\create, DI\get;

use Zend\Diactoros\Response\HtmlResponse;

use Picea\Picea,
    Picea\Caching\Cache,
    Picea\Caching\Opcache,
    Picea\Compiler,
    Picea\Compiler\Context,
    Picea\Compiler\BaseContext,
    Picea\Extension\LanguageHandler,
    Picea\Extension\LanguageExtension,
    Picea\Extension\TitleExtension,
    Picea\Extension\UrlExtension,
    Picea\FileFetcher,
    Picea\Language\DefaultRegistrations,
    Picea\Method\Request,
    Picea\Ui\Method,
    Picea\Ui\Ui;

return [
    Picea::class => function($c) {
        return new Picea(function($html) {
            return new HtmlResponse( $html );
        }, $c->get(Context::class), $c->get(Cache::class), $c->get(Compiler::class), null, $c->get(FileFetcher::class), null, getenv("DEBUG"));
    },

    Context::class => function($c) {
        return new BaseContext( $c->get(Lean\Lean::class)->getPiceaContext() );
    },

    Compiler::class => function($c) {
        return new Compiler(new class(array_merge([
            $c->get(LanguageExtension::class),
            $c->get(TitleExtension::class),
            $c->get(UrlExtension::class),
            $c->get(Method\Form::class),
            $c->get(Method\Pagination::class),
            $c->get(Request::class),
        ], array_map(fn($class) => $c->get($class), $c->get(Lean\Lean::class)->getPiceaExtensions() ))) extends DefaultRegistrations {

            public function registerAll(Compiler $compiler) : void
            {
                parent::registerAll($compiler);
                ( new Ui() )->registerFormExtension($compiler);
            }

        });
    },

    Request::class => autowire(Request::class),

    Method\Form::class => autowire(Method\Form::class),

    Method\Pagination::class => autowire(Method\Pagination::class),

    LanguageExtension::class => create(LanguageExtension::class)->constructor(get(LanguageHandler::class)),

    LanguageHandler::class => function($c) {
        return new class( $c->get(Tell\I18n::class) ) implements LanguageHandler {
            public Tell\I18n $tell;

            public function __construct(Tell\I18n $tell) {
                $this->tell = $tell;
            }

            public function languageFromKey(string $key, array $variables = []) #: array|string
            {
                return $this->tell->fromKey($key, $variables) ?: "";
            }
        };
    },

    TitleExtension::class => autowire(TitleExtension::class),

    UrlExtension::class => create(UrlExtension::class)->constructor(get(Context::class), getenv("URL_BASE"), get('git.commit')),

    Cache::class => create(Opcache::class)->constructor(getenv("CACHE_PATH"), get(Context::class)),

    FileFetcher::class => function($c) {
        return new FileFetcher($c->get(Lean\Lean::class)->getViewPaths());
    },
];