<?php 

namespace NPS\Command;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Process\Process;
use NPS\Etc\Strings;
use NPS\Etc\Files;
use NPS\Model\KnowledgeBase;

/**
 * Synchronizes known bases with a state of a remote git repository
 * @author Lukas Korinek
 */
class SynchronizeBasesGitCommand extends Command
{

    /** @var string $temp */
    private $temp;

    public function __construct($gitSyncTempDirectory) 
    {
        $this->temp = rtrim($gitSyncTempDirectory, "/\\");
        parent::__construct();
    }

    /**
     * @inheritdoc
     */
    protected function configure()
    {
        $this 
            ->setName('base:git')
            ->setDescription('Synchronizes known bases with a state of a remote git repository')
            ->addArgument('url', InputArgument::REQUIRED, 'Repository URL (SSH) serving as a source of bases')
            ->addArgument('branch', InputArgument::OPTIONAL, 'Branch which will be cloned');
    }   

    /**
     * @inheritdoc
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Validate SSH URL
        $url = trim($input->getArgument('url'));
        if(!Strings::isGitUrl($url, Strings::GIT_SSH))
        {
            $output->writeln('Invalid git repository SSH URL: ' . $url);
            return 1;
        }

        // Prepare directory
        if(!is_dir($this->temp))
        {
            @mkdir($this->temp, 0777);
        }
        $target = $this->temp . '/' . time();

        // Clone the repository
        $branch = trim($input->getArgument('branch')) ?: 'master';
        $process = new Process(sprintf('git clone --depth 1 -b %s %s %s', $branch, $url, $target));
        $process->start();
        
        if($process->wait() != 0)
        {
            $output->writeln('Git clone was not successful:');
            $output->writeln($process->getOutput());
        }

        // Iterate over its folders indicating resulting status of the knowledge base
        $reflection = new \ReflectionClass(KnowledgeBase::class);
        foreach(scandir($target) as $file)
        {
            $path = $target . '/' . $file;
            if(!is_dir($path) || $file == '.' || $file == '..')
            {
                continue;
            }

            // Validate base status string
            $status = 'STATUS_' . strtoupper($file);
            if($reflection->hasConstant($status))
            {

                $params = [
                    '--status' => $status,
                    'directory' => $path
                ];

                if($output->isVerbose())
                {
                    $params[] = '-vv';
                }
                
                // Run directory sync command
                $command = $this->getApplication()->find('base:sync');
                if($command->run(new ArrayInput($params), $output))
                {
                    $output->writeln('Failed to synchronize directory: ' . $path);
                    return 2;
                }

            }
        }

        // Cleanup the mess
        if(is_dir($target))
        {
            @Files::rrmdir($target);
        }

        return 0;

    }

}

