<?php

namespace Slovocast;

use Slim\App;
use Slim\Factory\AppFactory;
use League\Config\Configuration;
use DI\Container;
use DI\ContainerBuilder;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Slovocast\Routes;

class Bootstrap
{
    /**
     * Pulls out all the configuration schemas and configuration values. 
     *
     * @return Configuration
     */
    protected static function initConfig(): Configuration
    {
        $config = new Configuration();

        // set all configuration details

        return $config;
    }

    /**
     * Set up the Container with all of its definitions, as well as
     * initialization of configuration.
     *
     * @return Container
     */
    protected static function initContainer(): Container 
    {
        $containerBuilder = new ContainerBuilder();

        $config = self::initConfig();
        $containerBuilder->addDefinitions([
            'conifg' => $config,
            // more DI stuff
        ]);

        return $containerBuilder->build();
    }

    /**
     * Tasking the instaniated Application, sets up all the routes for the 
     * application.
     *
     * @param App $app
     * @return void
     */
    protected static function establishRoutes(App $app): void
    {
        Routes::init($app);
    }

    /**
     * Taking an instantiated application, sets up all the middleware required
     * for the application to run.
     *
     * @param App $app
     */
    protected static function establishMiddleware(App $app): void
    {
        $app->addErrorMiddleware(true, true, true);

        // Twig
        $templatePath = __DIR__ . "/../templates";
        $twig = Twig::create($templatePath, [ 'cache' => false ]);
        $app->add(TwigMiddleware::create($app, $twig));
    }

    /**
     * Instantiates the application.
     *
     * @return App
     */
    public static function init(): App
    {
        $container = self::initContainer();
        $app = AppFactory::createFromContainer($container);
        self::establishMiddleware($app);
        self::establishRoutes($app);
        return $app;
    }
}
