<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\Migrations\Report;

use Chill\MainBundle\Entity\Scope;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Add a scope to report.
 */
class Version20150622233319 extends AbstractMigration implements ContainerAwareInterface
{
    private ?ContainerInterface $container = null;

    public function down(Schema $schema): void
    {
        $this->abortIf(
            'postgresql' !== $this->connection->getDatabasePlatform()->getName(),
            'Migration can only be executed safely on \'postgresql\'.'
        );

        $this->addSql('ALTER TABLE Report DROP CONSTRAINT FK_report_scope');
        $this->addSql('DROP INDEX IDX_report_scope');
        $this->addSql('ALTER TABLE Report ADD scope VARCHAR(255) DEFAULT NULL');
        $this->addSql('ALTER TABLE Report DROP scope_id');
    }

    public function setContainer(?ContainerInterface $container = null)
    {
        if (null === $container) {
            throw new \RuntimeException('Container is not provided. This migration need container to set a default center');
        }

        $this->container = $container;
    }

    public function up(Schema $schema): void
    {
        $this->abortIf(
            'postgresql' !== $this->connection->getDatabasePlatform()->getName(),
            'Migration can only be executed safely on \'postgresql\'.'
        );

        $this->addSql('ALTER TABLE report ADD scope_id INT DEFAULT NULL');

        /*
         * Before the upgrade to symfony version 4, this code worked.
         *
         * But it doesn't work any more after the migration and currently this
         * code should note be necessary.
         *
         * This code is kept for reference, and may be re-activated if needed, but
         * the probability that this will happens is near 0
         *

        //add a default scope
        $scopes = $this->container->get('doctrine.orm.default_entity_manager')
              ->getRepository(\Chill\MainBundle\Entity\Scope::class)
              ->findAll();

        if (count($scopes) > 0) {
            $defaultScopeId = $scopes[0]->getId();
        } else {
            //check if there are data in report table
            $nbReports = $this->container->get('doctrine.orm.default_entity_manager')
                  ->createQuery('SELECT count(r.id) FROM ChillReportBundle:Report r')
                  ->getSingleScalarResult();

            if ($nbReports > 0) {
                //create a default scope
                $scope = new Scope();
                //create name according to installed languages
                $locales = $this->container
                      ->getParameter('chill_main.available_languages');
                $names = array();
                foreach($locales as $locale) {
                    $names[$locale] = 'default';
                }
                $scope->setName($names);
                //persist
                $this->container->get('doctrine.orm.default_entity_manager')
                      ->persist($scope);
                $this->container->get('doctrine.orm.default_entity_manager')
                      ->flush();
                //default scope is the newly-created one
                $defaultScopeId = $scope->getId();
            }
        }*/

        $this->addSql('ALTER TABLE report DROP scope'); // before this migration, scope was never used
        $this->addSql('ALTER TABLE report ADD CONSTRAINT FK_report_scope '
                .'FOREIGN KEY (scope_id) '
                .'REFERENCES scopes (id) NOT DEFERRABLE INITIALLY IMMEDIATE');

        if (isset($defaultScopeId)) {
            $this->addSql('UPDATE report SET scope_id = :id', [
                'id' => $defaultScopeId,
            ]);
        }
        $this->addSql('ALTER TABLE report ALTER COLUMN scope_id SET NOT NULL');
        $this->addSql('CREATE INDEX IDX_report_scope ON report (scope_id)');
    }
}
