<?php

/*
 * This file is part of Anis Server.
 *
 * (c) Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare(strict_types=1);

use Psr\Container\ContainerInterface;

// Load settings
$container->set(SETTINGS, function () {
    return include __DIR__ . '/../app/settings.php';
});

// Doctrine factory
$container->set('em', function (ContainerInterface $c) {
    $settings = $c->get(SETTINGS)['database'];
    $devMode = boolval($settings['dev_mode']);
    $proxyDir = '/project/doctrine-proxy';

    if ($devMode) {
        $cache = \Doctrine\Common\Cache\Psr6\DoctrineProvider::wrap(
            new \Symfony\Component\Cache\Adapter\ArrayAdapter()
        );
    } else {
        $cache = \Doctrine\Common\Cache\Psr6\DoctrineProvider::wrap(
            new \Symfony\Component\Cache\Adapter\FilesystemAdapter(directory: '/project/doctrine_cache')
        );
    }

    $dc = \Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration(
        array('src/Entity'),
        $devMode,
        $proxyDir,
        $cache
    );
    $dc->setAutogenerateProxyClasses(false);

    if ($devMode) {
        $dc->setSQLLogger(new \Doctrine\DBAL\Logging\DebugStack());
    }

    return \Doctrine\ORM\EntityManager::create($settings['connection_options'], $dc);
});

// Monolog factory
$container->set('logger', function (ContainerInterface $c) {
    $loggerSettings = $c->get('settings')['logger'];
    $logger = new \Monolog\Logger($loggerSettings['name']);
    $logger->pushProcessor(new \Monolog\Processor\UidProcessor());
    $logger->pushHandler(new \Monolog\Handler\StreamHandler($loggerSettings['path'], $loggerSettings['level']));
    return $logger;
});

// RabbitMQ connection factory
$container->set('rmq', function (ContainerInterface $c) {
    $rmqSettings = $c->get('settings')['rmq'];
    return new \PhpAmqpLib\Connection\AMQPStreamConnection(
        $rmqSettings['host'],
        $rmqSettings['port'],
        $rmqSettings['user'],
        $rmqSettings['password']
    );
});

// Actions
$container->set('App\Action\RootAction', function () {
    return new App\Action\RootAction();
});

$container->set('App\Action\ClientSettingsAction', function (ContainerInterface $c) {
    return new App\Action\ClientSettingsAction($c->get(SETTINGS));
});

$container->set('App\Action\SelectListAction', function (ContainerInterface $c) {
    return new App\Action\SelectListAction($c->get('em'));
});

$container->set('App\Action\SelectAction', function (ContainerInterface $c) {
    return new App\Action\SelectAction($c->get('em'));
});

$container->set('App\Action\OptionListAction', function (ContainerInterface $c) {
    return new App\Action\OptionListAction($c->get('em'));
});

$container->set('App\Action\OptionAction', function (ContainerInterface $c) {
    return new App\Action\OptionAction($c->get('em'));
});

$container->set('App\Action\DatabaseListAction', function (ContainerInterface $c) {
    return new App\Action\DatabaseListAction($c->get('em'));
});

$container->set('App\Action\DatabaseAction', function (ContainerInterface $c) {
    return new App\Action\DatabaseAction($c->get('em'));
});

$container->set('App\Action\TableListAction', function (ContainerInterface $c) {
    return new App\Action\TableListAction($c->get('em'), new App\Search\DBALConnectionFactory());
});

$container->set('App\Action\ColumnListAction', function (ContainerInterface $c) {
    return new App\Action\ColumnListAction($c->get('em'), new App\Search\DBALConnectionFactory());
});

$container->set('App\Action\AdminFileExplorerAction', function (ContainerInterface $c) {
    return new App\Action\AdminFileExplorerAction($c->get('settings')['data_path']);
});

$container->set('App\Action\InstanceGroupListAction', function (ContainerInterface $c) {
    return new App\Action\InstanceGroupListAction($c->get('em'));
});

$container->set('App\Action\InstanceGroupAction', function (ContainerInterface $c) {
    return new App\Action\InstanceGroupAction($c->get('em'));
});

$container->set('App\Action\SurveyListAction', function (ContainerInterface $c) {
    return new App\Action\SurveyListAction($c->get('em'));
});

$container->set('App\Action\SurveyAction', function (ContainerInterface $c) {
    return new App\Action\SurveyAction($c->get('em'));
});

$container->set('App\Action\GroupListAction', function (ContainerInterface $c) {
    return new App\Action\GroupListAction($c->get('em'));
});

$container->set('App\Action\GroupAction', function (ContainerInterface $c) {
    return new App\Action\GroupAction($c->get('em'));
});

$container->set('App\Action\InstanceListAction', function (ContainerInterface $c) {
    return new App\Action\InstanceListAction($c->get('em'), $c->get(SETTINGS)['token']);
});

$container->set('App\Action\InstanceAction', function (ContainerInterface $c) {
    return new App\Action\InstanceAction($c->get('em'));
});

$container->set('App\Action\DatasetFamilyListAction', function (ContainerInterface $c) {
    return new App\Action\DatasetFamilyListAction($c->get('em'));
});

$container->set('App\Action\DatasetListByInstanceAction', function (ContainerInterface $c) {
    return new App\Action\DatasetListByInstanceAction($c->get('em'), $c->get(SETTINGS)['token']);
});

$container->set('App\Action\DatasetFamilyAction', function (ContainerInterface $c) {
    return new App\Action\DatasetFamilyAction($c->get('em'));
});

$container->set('App\Action\DatasetListAction', function (ContainerInterface $c) {
    return new App\Action\DatasetListAction($c->get('em'));
});

$container->set('App\Action\DatasetAction', function (ContainerInterface $c) {
    return new App\Action\DatasetAction($c->get('em'));
});

$container->set('App\Action\CriteriaFamilyListAction', function (ContainerInterface $c) {
    return new App\Action\CriteriaFamilyListAction($c->get('em'));
});

$container->set('App\Action\CriteriaFamilyAction', function (ContainerInterface $c) {
    return new App\Action\CriteriaFamilyAction($c->get('em'));
});

$container->set('App\Action\OutputFamilyListAction', function (ContainerInterface $c) {
    return new App\Action\OutputFamilyListAction($c->get('em'));
});

$container->set('App\Action\OutputFamilyAction', function (ContainerInterface $c) {
    return new App\Action\OutputFamilyAction($c->get('em'));
});

$container->set('App\Action\OutputCategoryListByDatasetAction', function (ContainerInterface $c) {
    return new App\Action\OutputCategoryListByDatasetAction($c->get('em'));
});

$container->set('App\Action\OutputCategoryListAction', function (ContainerInterface $c) {
    return new App\Action\OutputCategoryListAction($c->get('em'));
});

$container->set('App\Action\OutputCategoryAction', function (ContainerInterface $c) {
    return new App\Action\OutputCategoryAction($c->get('em'));
});

$container->set('App\Action\AttributeListAction', function (ContainerInterface $c) {
    return new App\Action\AttributeListAction($c->get('em'));
});

$container->set('App\Action\AttributeAction', function (ContainerInterface $c) {
    return new App\Action\AttributeAction($c->get('em'));
});

$container->set('App\Action\AttributeDistinctAction', function (ContainerInterface $c) {
    return new App\Action\AttributeDistinctAction($c->get('em'), new App\Search\DBALConnectionFactory());
});

$container->set('App\Action\SearchAction', function (ContainerInterface $c) {
    $anisQueryBuilder = (new App\Search\Query\AnisQueryBuilder())
        ->addQueryPart(new App\Search\Query\From())
        ->addQueryPart(new App\Search\Query\Count())
        ->addQueryPart(new App\Search\Query\SelectAll())
        ->addQueryPart(new App\Search\Query\Select())
        ->addQueryPart(new App\Search\Query\ConeSearch())
        ->addQueryPart(new App\Search\Query\Where(new App\Search\Query\Operator\OperatorFactory()))
        ->addQueryPart(new App\Search\Query\Order())
        ->addQueryPart(new App\Search\Query\Limit());

    return new App\Action\SearchAction(
        $c->get('em'),
        new App\Search\DBALConnectionFactory(),
        $anisQueryBuilder,
        new App\Search\Response\ResponseFactory(),
        $c->get(SETTINGS)['token']
    );
});

$container->set('App\Action\StartTaskCreateResultAction', function (ContainerInterface $c) {
    return new App\Action\StartTaskCreateResultAction($c->get('em'), $c->get('rmq'), $c->get(SETTINGS)['token']);
});

$container->set('App\Action\IsResultAvailableAction', function (ContainerInterface $c) {
    return new App\Action\IsResultAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['result_folder']);
});

$container->set('App\Action\DownloadResultAction', function (ContainerInterface $c) {
    return new App\Action\DownloadResultAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['result_folder'], $c->get(SETTINGS)['token']);
});

$container->set('App\Action\StartTaskCreateArchiveAction', function (ContainerInterface $c) {
    return new App\Action\StartTaskCreateArchiveAction($c->get('em'), $c->get('rmq'), $c->get(SETTINGS)['token']);
});

$container->set('App\Action\IsArchiveAvailableAction', function (ContainerInterface $c) {
    return new App\Action\IsArchiveAvailableAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['archive_folder']);
});

$container->set('App\Action\DownloadArchiveAction', function (ContainerInterface $c) {
    return new App\Action\DownloadArchiveAction($c->get('em'), $c->get('settings')['data_path'], $c->get('settings')['archive_folder'], $c->get(SETTINGS)['token']);
});

$container->set('App\Action\DatasetFileExplorerAction', function (ContainerInterface $c) {
    return new App\Action\DatasetFileExplorerAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
});

$container->set('App\Action\DownloadInstanceFileAction', function (ContainerInterface $c) {
    return new App\Action\DownloadInstanceFileAction($c->get('em'), $c->get('settings')['data_path']);
});

$container->set('App\Action\DownloadFileAction', function (ContainerInterface $c) {
    return new App\Action\DownloadFileAction($c->get('em'), $c->get('settings')['data_path'], $c->get(SETTINGS)['token']);
});