<?php

declare(strict_types = 1);

use App\Core\GNUsocial;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Persistence\ManagerRegistry;
use Functional as F;
use Symfony\Component\Dotenv\Dotenv;

require \dirname(__DIR__) . '/vendor/autoload.php';

if (file_exists(\dirname(__DIR__) . '/config/bootstrap.php')) {
    require \dirname(__DIR__) . '/config/bootstrap.php';
} elseif (method_exists(Dotenv::class, 'bootEnv')) {
    (new Dotenv())->bootEnv(\dirname(__DIR__) . '/.env');
}

global $APP_KERNEL;

if (isset($_ENV['APP_ENV'])) {
    $env = $_ENV['APP_ENV'];
} elseif (isset($_SERVER['APP_ENV'])) {
    $env = $_SERVER['APP_ENV'];
} else {
    $env = 'test';
}

if (isset($_ENV['APP_DEBUG'])) {
    $debug = $_ENV['APP_DEBUG'];
} elseif (isset($_SERVER['APP_DEBUG'])) {
    $debug = $_SERVER['APP_DEBUG'];
} else {
    $debug = true;
}

ini_set('memory_limit', '1G');

$APP_KERNEL = new \App\Kernel($env, (bool) $debug);
$APP_KERNEL->boot();

$container = $APP_KERNEL->getContainer()->get('test.service_container');

$services = F\map(
    (new \ReflectionClass(GNUsocial::class))->getMethod('__construct')->getParameters(),
    fn ($p) => $container->get((string) $p->getType()),
);
global $GNUSOCIAL;
$GNUSOCIAL = new GNUsocial(...$services);

$doctrine      = $container->get(ManagerRegistry::class);
$em            = $container->get(EntityManagerInterface::class);
$connection    = $doctrine->getConnection();
$params        = $connection->getParams();
$tmpConnection = DriverManager::getConnection($params);
$name          = $params['dbname'];
if (!\in_array($name, $tmpConnection->getSchemaManager()->listDatabases())) {
    unset($params['dbname'], $params['path'], $params['url']);
    $tmpConnection = DriverManager::getConnection($params);
    $tmpConnection->getSchemaManager()->createDatabase($name);

    $metadatas  = $em->getMetadataFactory()->getAllMetadata();
    $schemaTool = new SchemaTool($em);
    $schemaTool->createSchema($metadatas);

    $fixturesLoader = $container->get('doctrine.fixtures.loader');
    $fixtures       = $fixturesLoader->getFixtures();
    $executor       = new ORMExecutor($em);
    $executor->execute($fixtures, append: true);

    $tmpConnection->close();
    echo "Created database {$name}\n";
}

$connection->connect();

$connection->setNestTransactionsWithSavepoints(true);
$connection->beginTransaction();
register_shutdown_function(function ($connection) {
    echo 'Rolling back changes';
    $connection->rollBack();
}, $connection);
