<?php /* EL PSY CONGROO */    		  			 
    	 	     
namespace Guzzle\Plugin\ErrorResponse;    		  	   
       	  	 
use Guzzle\Common\Event;        			 
use Guzzle\Http\Message\RequestInterface;    	  		 	 
use Guzzle\Service\Command\CommandInterface;    		   	 	
use Guzzle\Service\Description\Operation;    			  	 	
use Guzzle\Plugin\ErrorResponse\Exception\ErrorResponseException;    	  	    
use Symfony\Component\EventDispatcher\EventSubscriberInterface;    	   	 	 
    		 	 			
/**     	  				
 * Converts generic Guzzle response exceptions into errorResponse exceptions    		 	  	 
 */     			 			
class ErrorResponsePlugin implements EventSubscriberInterface    	 	 				
{    		  		 	
    public static function getSubscribedEvents()        		  
    {     			  		
        return array('command.before_send' => array('onCommandBeforeSend', -1));       	    
    }    	 	   		
    	    	  
    /**    	 	  	 	
     * Adds a listener to requests before they sent from a command    		 	 			
     *      	 		  
     * @param Event $event Event emitted    		  	  	
     */         			
    public function onCommandBeforeSend(Event $event)    	 	 	 	 
    {      	   	 
        $command = $event['command'];    		 	  		
        if ($operation = $command->getOperation()) {     	  	   
            if ($operation->getErrorResponses()) {     	 	  	 
                $request = $command->getRequest();     	 	 			
                $request->getEventDispatcher()      					 
                    ->addListener('request.complete', $this->getErrorClosure($request, $command, $operation));    	   		 	
            }      	 			 
        }    			     
    }    			   		
     				 		
    /**     	 	 			
     * @param RequestInterface $request   Request that received an error    	   	 	 
     * @param CommandInterface $command   Command that created the request    			  		 
     * @param Operation        $operation Operation that defines the request and errors     		  		 
     *    		      
     * @return \Closure Returns a closure    	 		  		
     * @throws ErrorResponseException       	 	 	
     */      			 	 
    protected function getErrorClosure(RequestInterface $request, CommandInterface $command, Operation $operation)      	  		 
    {      	 	 	 
        return function (Event $event) use ($request, $command, $operation) {         		 
            $response = $event['response'];      	   		
            foreach ($operation->getErrorResponses() as $error) {    		 	 			
                if (!isset($error['class'])) {      	  	 	
                    continue;          	 
                }    	 	  	  
                if (isset($error['code']) && $response->getStatusCode() != $error['code']) {    			 	 		
                    continue;    				  	 
                }    	 	 	 	 
                if (isset($error['reason']) && $response->getReasonPhrase() != $error['reason']) {    	 		  		
                    continue;         			
                }    	   	 		
                $className = $error['class'];     	  			 
                $errorClassInterface = __NAMESPACE__ . '\\ErrorResponseExceptionInterface';     	  			 
                if (!class_exists($className)) {    	    	 	
                    throw new ErrorResponseException("{$className} does not exist");    	  	 	  
                } elseif (!(in_array($errorClassInterface, class_implements($className)))) {         			
                    throw new ErrorResponseException("{$className} must implement {$errorClassInterface}");     			 			
                }       		 		
                throw $className::fromCommand($command, $response);    			  		 
            }     	 		 		
        };     		    	
    }     	   	  
}      						
     		  	  