<?php

namespace Comitium5\DesignerBundle\Publisher;

use Comitium5\DesignerBundle\Helper\FileUtils;
use Comitium5\DesignerBundle\Manager\Designer\DesignerManager;
use Comitium5\DesignerBundle\Manager\View\ViewManager;
use Comitium5\DesignerBundle\Model\Interfaces\Page\PageInterface;
use Comitium5\DesignerBundle\Model\Interfaces\PublisherInterface;
use Monolog\Logger;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
 * Class Publisher
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Publisher
 */
class Publisher implements PublisherInterface
{
    /**
     * @var array
     */
    protected $targetPaths;

    /**
     * @var
     */
    private $kernel;

    /**
     * @var Logger
     */
    private $logger;

    /**
     * @var ViewManager
     */
    private $viewManager;

    /**
     * Publisher constructor.
     *
     * @param $kernel
     * @param Logger $logger
     * @param ViewManager $viewManager
     */
    public function __construct($kernel, Logger $logger, ViewManager $viewManager)
    {
        $this->kernel = $kernel;
        $this->logger = $logger;
        $this->viewManager = $viewManager;
    }

    /**
     * @param array $paths
     *
     * @throws \Exception
     */
    public function publish(array $paths)
    {
        foreach ($this->targetPaths as $targetPath) {
            foreach ($paths as $path => $content) {
                FileUtils::create(
                    $targetPath.$path,
                    $content
                );
            }
        }

        try {
            $this->refreshCache();
        } catch (\Throwable $e) {
            $this->logger->addError($e->getMessage());
        }
    }

    /**
     * @param array $paths
     * @param PageInterface $page
     *
     * @throws \Exception
     */
    public function publishToDB(array $paths, PageInterface $page)
    {
        foreach ($paths as $path => $content) {
            $this
                ->viewManager
                ->create(
                    sprintf(
                        DesignerManager::CACHE_TWIG_PATH,
                        $path
                    ),
                    $content,
                    $page
                );
        }
    }

    /**
     * @param array $paths
     */
    public function removeFiles(array $paths)
    {
        $fileSystem = new Filesystem();

        foreach ($this->targetPaths as $targetPath) {
            foreach ($paths as $path) {
                $fileSystem->remove($targetPath.$path);
            }
        }
    }

    /**
     * @return mixed
     */
    public function buildTargetPaths()
    {
        // Implement for multiple subsites if is needed
        //        $paths = [];
        //
        //        foreach ($this->targetPaths as &$path) {
        //            $path = $path.DIRECTORY_SEPARATOR.$subSite->getId();
        //        }
        //
        //        return $paths;
        return $this->targetPaths;
    }

    /**
     * @return bool
     */
    public function refreshCache()
    {
        $command = sprintf("%s/console assets:install --symlink --env=%s ../web",
            $this->kernel->getRootDir(),
            $this->kernel->getEnvironment());

        $process = new Process($command);
        $process->run();

        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }

        return true;
    }

    /**
     * @return mixed
     */
    public function getTargetPaths()
    {
        return $this->targetPaths;
    }

    /**
     * @param mixed $targetPaths
     */
    public function setTargetPaths($targetPaths)
    {
        $this->targetPaths = $targetPaths;
    }
}
