<?php
/**
 * ControllerBase
 * 
 * Base Controller where FolderController and FileController extend
 * on. 
 * 
 * @author Visual Media
 */

namespace VisualM\MediaManagerBundle\Controller;

use InvalidArgumentException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\Translator;
use VisualM\MediaManagerBundle\Configuration\ConfigurationInterface;
use VisualM\MediaManagerBundle\Configuration\ConfigurationProviderInterface;

/**
 * ControllerBase
 * 
 * @author Visual Media
 */
abstract class ControllerBase extends Controller
{
 
    /**
     * ConfigurationProvider
     * @var ConfigurationProviderInterface 
     */
    private $configuration_provider;
    
    /**
     * Translator
     * @var Translator
     */
    protected $translator;
    
    /**
     * Constructor
     * @param ContainerInterface $container              Container
     * @param string             $configuration_provider ConfigurationProvider
     * @param Translator         $translator             Translator
     */
    function __construct(ContainerInterface $container, $configuration_provider, Translator $translator)
    {
        // Check if service is given
        if (substr($configuration_provider, 0, 1) == '@') {
            $provider = $container->get(substr($configuration_provider, 1));
        } else {
            $provider = new $configuration_provider();
        }
        
        if (!($provider instanceof ConfigurationProviderInterface)) {
            throw new \Exception("Configuration provider should be an implementation of ConfigurationProviderInterface");
        }
        
        $this->configuration_provider = $provider;
        $this->translator = $translator;
        
    }
    
    /**
     * Get Extra Arguments
     * 
     * Retrieve list of parameters that should be added to each forward,
     * think of callbacks etc.
     * 
     * @param Request $request Request
     * 
     * @return array Arguments
     */
    protected function getExtraArgs(Request $request) {
        return array(
            'fs_callback' => $request->query->get('fs_callback', null),
            'CKEditor' => $request->query->get('CKEditor', null),
            'CKEditorFuncNum' => $request->query->get('CKEditorFuncNum', null),
            'langCode' => $request->query->get('langCode', null),
            'multi_select' => $request->query->get('multi_select', null),
        );
    }
    
    /**
     * Get Configuration for given Key
     * 
     * @param string $key Key
     * 
     * @return ConfigurationInterface Configuration
     */
    protected function getConfiguration($key)
    {
        return $this->configuration_provider->getConfiguration($key);
    }

    /**
     * Get Full Path for given relative path
     * 
     * This function adds the relative path to the base path and
     * if check is set ensures that the constructed absolute is within the 
     * base path
     * 
     * @param string  $base_path Base Path
     * @param string  $relative  Relative path
     * @param boolean $checl     Check if path is within base path
     * 
     * @return void
     */
    public function getFullpath($base_path, $relative, $check = true) 
    {        
        if (substr($base_path, -1, 1) != DIRECTORY_SEPARATOR)  {
            $base_path .= DIRECTORY_SEPARATOR;
        }
        
        $path = realpath($base_path . $relative);
        if (is_dir($path)) {
            $path .= DIRECTORY_SEPARATOR;
        }
        
        if ($check AND empty($path)) {
            throw new InvalidArgumentException(sprintf('Relative path "%s" cannot be resolved into an absolute path.', $relative));            
        } else if ($check AND (strpos($path, substr($base_path, 0, -1)) !== 0)) {
            throw new InvalidArgumentException(sprintf('Relative path "%s" is outside the given base path.', $relative));            
        }
        
        return $path;
    }
    
}