<?php
namespace Sso\WebserviceBundle\Security\Api\Firewall\Level;

use Sso\WebserviceBundle\Security\Api\Manager as ApiManager;
use Sso\WebserviceBundle\Security\Exception\FirewallException;

/**
 * Class Two
 * @package Sso\WebserviceBundle\Security\Api\Firewall\Level
 */
class Two
{
    const FIREWALL_LEVEL_ERROR_CODE = "fw002";

    /**
     * @var ApiManager
     */
    private $apiM;

    /**
     * @var \Sso\WebserviceBundle\ErrorHandler\ErrorStorage\Factory
     */
    private $errorStorage;


    /**
     * Factory constructor.
     * @param ApiManager $apiM
     */
    public function __construct(ApiManager $apiM)
    {
        $this->apiM = $apiM;
        $this->errorStorage = $this->apiM->getErrorHandler()->errorStorage();
    }

    /**
     * @param string $xmlString
     * @param string $headerController
     * @param string $headerAction
     * @return bool
     * @throws FirewallException
     */
    public function checkXmlAndControllerAction($xmlString, $headerController, $headerAction)
    {
        libxml_clear_errors();
        libxml_disable_entity_loader(true);
        libxml_use_internal_errors(true);

        $simpleXML = simplexml_load_string($xmlString, "SimpleXMLElement", LIBXML_COMPACT);

        if (!$simpleXML) {
            $errors = libxml_get_errors();
            foreach ($errors as $error) {
                $this->errorStorage->setErrorFromValues(400, static::FIREWALL_LEVEL_ERROR_CODE, 'hd003','XmlInvalid', $error->message);
            }
            libxml_clear_errors();
            libxml_disable_entity_loader(false);
        } else {
            libxml_clear_errors();
            libxml_disable_entity_loader(false);
        }
        if ($this->errorStorage->hasErrors()) {
            throw new FirewallException('Firewall Level Two Exception');
        }

        if (!isset($simpleXML->{$headerController})) {

            // For BC: overwrite controller and action from header
            $this->errorStorage->setController('Unknown');
            $this->errorStorage->setAction('Unknown');
            $this->errorStorage->setErrorFromValues(400, static::FIREWALL_LEVEL_ERROR_CODE, 'hd004', 'XML Controller', 'Controller in header does not match controller in xml');
            throw new FirewallException('Firewall Level Two Exception');
        }

        if (!isset($simpleXML->{$headerController}->{$headerAction})) {

            // For BC: overwrite action from header
            $this->errorStorage->setAction('Unknown');
            $this->errorStorage->setErrorFromValues(400, static::FIREWALL_LEVEL_ERROR_CODE, 'hd005', 'XML Action', 'Action in header does not match controller in xml');
            throw new FirewallException('Firewall Level Two Exception');
        }

        return true;
    }
}
