<?php

namespace Lc\SovBundle\Maker;

use Doctrine\Common\Annotations\Annotation;
use Symfony\Bundle\MakerBundle\ConsoleStyle;
use Symfony\Bundle\MakerBundle\DependencyBuilder;
use Symfony\Bundle\MakerBundle\Generator;
use Symfony\Bundle\MakerBundle\InputConfiguration;
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;

use function Symfony\Component\String\u;

class RepositoryMaker extends AbstractMaker
{
    public static function getCommandName(): string
    {
        return 'make:repository';
    }

    public static function getCommandDescription(): string
    {
        return 'Creates a repository, query and store';
    }

    public function configureCommand(Command $command, InputConfiguration $inputConf)
    {
        $command
                ->addArgument(
                        'namespace',
                        InputArgument::OPTIONAL,
                        'Namespace (e.g. <fg=yellow>Lc\SovBundle\Repository</>)'
                )
                ->addArgument(
                        'domain',
                        InputArgument::OPTIONAL,
                        'Domain (e.g. <fg=yellow>Order</>)'
                )
                ->addArgument(
                        'entity-class',
                        InputArgument::OPTIONAL,
                        'Define the entity (e.g. <fg=yellow>MyEntity</>)'
                )
                ->setHelp('');
    }

    public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator)
    {
        $entityDetails = $generator->createClassNameDetails(
                $input->getArgument('entity-class'),
                'Entity\\',
                ''
        );

        $options = [
                'namespace_path' => $input->getArgument('namespace'),
                'domain' => $input->getArgument('domain'),
                'entity_class' => $input->getArgument('entity-class'),
                'entity' => $entityDetails->getFullName(),
        ];

        // repository
        $repositoryClass = $input->getArgument('entity-class') . 'Repository';
        $this->generateClass($generator, $repositoryClass, 'Repository\\', 'repository.tpl.php', $options);

        // repository query
        $repositoryQueryClass = $input->getArgument('entity-class') . 'RepositoryQuery';
        $options['class_name_repository'] = $repositoryClass;
        $this->generateClass($generator, $repositoryQueryClass, 'Repository\\', 'repository_query.tpl.php', $options);

        // store
        $storeClass = $input->getArgument('entity-class') . 'Store';
        $options['class_name_repository_query'] = $repositoryQueryClass;
        $this->generateClass($generator, $storeClass, 'Repository\\', 'store.tpl.php', $options);

        // interfaces
        //$this->generateInterface($input, $generator, $repositoryQueryClass . 'Interface');
        //$this->generateInterface($input, $generator, $storeClass . 'Interface');

        // write files
        $generator->writeChanges();

        $this->writeSuccessMessage($io);
        $io->text('Next: Open your new factory class and configure it!');
    }

    public function generateClass($generator, $class, $namespacePrefix, $tpl, $options)
    {
        $repositoryDetails = $generator->createClassNameDetails(
                $class,
                $namespacePrefix,
                ''
        );
        $generator->generateController(
                $repositoryDetails->getFullName(),
                __DIR__ . '/../Resources/maker/repository/'.$tpl,
                $options
        );
    }

    public function generateInterface($input, $generator, $interfaceName)
    {
        $generator->generateFile(
                $generator->getRootDirectory() . '/src/Repository/' . $interfaceName . '.php',
                __DIR__ . '/../Resources/maker/repository/interface.tpl.php',
                [
                        'namespace_path' => $input->getArgument('namespace'),
                        'domain' => $input->getArgument('domain'),
                        'interface_name' => $interfaceName,
                ]
        );
    }


    public function configureDependencies(DependencyBuilder $dependencies)
    {
        $dependencies->addClassDependency(
                Annotation::class,
                'doctrine/annotations'
        );
    }
}
