<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace LifeStyle\DH\AttributeGeneratorBundle\Controller;

use Doctrine\DBAL\DBALException;
use Doctrine\ORM\EntityManagerInterface;
use JMS\SecurityExtraBundle\Annotation\Secure;
use LifeStyle\DH\AttributeGeneratorBundle\Entity\AttributeEmployeeId;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;

/**
 * Class GenerateController
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */
class GenerateController extends Controller
{
    /**
     * @see https://support.life-style.de/browse/DH-148
     * @var array
     */
    private $reservedEmployeeIds = [
        100740,
        104840,
        104760,
    ];

    /**
     * @Secure(roles="ROLE_ADMIN")
     * @Route(path="", name="attribute_unique_generator_index", methods={"GET"})
     * @return Response
     */
    public function indexAction(): Response
    {
        return $this->render('@AttributeGenerator/generate.html.twig', ['count' => $this->countEmployeeIds()]);
    }

    /**
     * Generate a list of employee-ids to be used as attribute value later
     *
     * @Secure(roles="ROLE_SUPER_ADMIN")
     * @Route(path="/generate", name="attribute_unique_generator_generate", methods={"POST"})
     * @return Response
     * @throws DBALException
     */
    public function generateAction(): Response
    {
        /** @var EntityManagerInterface $objectManager */
        $objectManager = $this->get('doctrine.orm.webservice_entity_manager');

        // Truncate table - dirty but fast
        $cmd = $objectManager->getClassMetadata(AttributeEmployeeId::class);
        $connection = $objectManager->getConnection();
        $query = $connection->getDatabasePlatform()->getTruncateTableSql($cmd->getTableName());
        $connection->executeUpdate($query);

        // Create new entries
        $employeeId = 1;
        do {
            // Create numbers with pattern 1-9|0|0-99|1-9|0
            $digits = array_map('intval', str_split(sprintf('%06d', $employeeId)));
            if (
                $digits[0] > 0 &&
                $digits[1] === 0 &&
                10 * $digits[2] + $digits[3] > 0 &&
                $digits[4] > 0 &&
                $digits[5] === 0 &&
                !in_array($employeeId, $this->reservedEmployeeIds)
            ) {
                $objectManager->persist(AttributeEmployeeId::create($employeeId));
            }
        } while(++$employeeId < 1000000);

        $objectManager->flush();

        return new JsonResponse(['count' => $this->countEmployeeIds()]);
    }

    /**
     * @Secure(roles="ROLE_SUPER_ADMIN")
     * @Route(path="/remove-reserved", name="attribute_unique_generator_remove_reserved", methods={"POST"})
     * @return Response
     * @throws DBALException
     */
    public function removeReservedAction(): Response
    {
        /** @var EntityManagerInterface $objectManager */
        $objectManager = $this->get('doctrine.orm.webservice_entity_manager');

        $sql = 'DELETE FROM dh_attribute_employee_id WHERE id IN (SELECT employeeId FROM dh_employee_id)';
        $objectManager->getConnection()->prepare($sql)->execute();

        return new JsonResponse(['count' => $this->countEmployeeIds()]);
    }

    /**
     * @return int
     */
    private function countEmployeeIds(): int
    {
        /** @var EntityManagerInterface $objectManager */
        $objectManager = $this->get('doctrine.orm.webservice_entity_manager');

        $qb = $objectManager->createQueryBuilder();
        $qb->select('count(a.id)');
        $qb->from(AttributeEmployeeId::class,'a');

        return (int)$qb->getQuery()->getSingleScalarResult();
    }
}
