<?php

/**
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected 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  2018 Lifestyle Webconsulting GmbH
 * @version    $Id:$
 * @link       http://www.life-style.de
 */

namespace LifeStyle\Tools\WebserviceBundle\Routing;

use Sensio\Bundle\FrameworkExtraBundle\Routing\AnnotatedRouteControllerLoader as SensioAnnotationClassLoader;
use Symfony\Component\Routing\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route as FrameworkExtraBundleRoute;
use LifeStyle\Tools\WebserviceBundle\Configuration\WsRoute;

/**
 * Class WsAnnotatedRouteControllerLoader
 * @package LifeStyle\Tools\WebserviceBundle\Routing
 */
class WsAnnotatedRouteControllerLoader extends SensioAnnotationClassLoader
{

    /**
     * Configures the _controller default parameter and eventually the _method
     * requirement of a given Route instance.
     *
     * @param Route $route A route instance
     * @param \ReflectionClass $class A ReflectionClass instance
     * @param \ReflectionMethod $method A ReflectionClass method
     * @param mixed $annot The annotation class instance
     *
     * @throws \LogicException When the service option is specified on a method
     */
    protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot)
    {
        parent::configureRoute($route, $class, $method, $annot);

        foreach ($this->reader->getMethodAnnotations($method) as $configuration) {
            if ($configuration instanceof WsRoute) {
                $this->setWsRoute($route, $class, $method, $configuration);
                break;
            }
        }
    }

    /**
     * Set routing parameters for webservice actions
     *
     * @param Route $route
     * @param \ReflectionClass $class
     * @param \ReflectionMethod $method
     * @param WsRoute $wsRoute
     */
    protected function setWsRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, WsRoute $wsRoute)
    {
        $conditions = array();
        if (strlen($route->getCondition())) {
            $conditions[] = $route->getCondition();
        }

        if (!$wsRoute->getController()) {
            $classAnnot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass);
            if ($classAnnot instanceof FrameworkExtraBundleRoute && $service = $classAnnot->getService()) {
                $wsRoute->setController($service);
            } else {
                $wsRoute->setController(preg_replace('/^.*\\\([^\\\]+)Controller$/', '$1', $class->getName()));
            }
        }
        $conditions[] = 'request.headers.get("sso-api-controller") == "' . $wsRoute->getController() . '"';

        if (!$wsRoute->getAction()) {
            $wsRoute->setAction(ucfirst(preg_replace('/Action$/', '', $method->getName())));
        }
        $conditions[] = 'request.headers.get("sso-api-action") == "' . $wsRoute->getAction() . '"';

        $route->setCondition(implode(' and ', $conditions));
    }
}
