<?php

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

namespace Sso\WebserviceBundle\Tests\Functional\Services\Helper\Version1;

use Sso\WebserviceBundle\Tests\FunctionalTestCase as FunctionalTestCaseBase;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Component\HttpFoundation\Response;
use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Configuration;
use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Version1\Factory as HelperFactory;

/**
 * Class FunctionalTestCase
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Version1
 */
abstract class FunctionalTestCase extends FunctionalTestCaseBase
{
    const API_VERSION = '1';

    /**
     * @var Configuration
     */
    protected $configuration;

    /**
     * @var Client
     */
    protected $client;

    /**
     * @var HelperFactory
     */
    protected $helperFactory;

    /**
     * @param string $filename
     * @param string $rootElement
     * @return \DOMElement
     */
    protected function loadXmlDomElement($filename, $rootElement)
    {
        $xmlDomExpected = new \DOMDocument();
        $xmlDomExpected->load($filename);
        return $xmlDomExpected->getElementsByTagName($rootElement)->item(0);
    }

    /**
     * @param string $controller
     * @param string $action
     * @param string $requestBody
     * @param array $additionalHeaders
     * @return Response
     */
    protected function sendPostRequest($controller, $action, $requestBody, array $additionalHeaders = [])
    {
        $headers = array_merge([
            'HTTP_API-CONTROLLER' => $controller,
            'HTTP_API-ACTION' => $action,
            'CONTENT-TYPE' => 'text/xml; charset=UTF-8',
            'HTTP_API-VERSION' => static::API_VERSION,
            'HTTP_REMOTE_ADDR' => '127.0.0.1',
        ], $additionalHeaders);

        $client = static::createClient();
        $client->request(
            'POST',
            $this->configuration->getUrlUserWs(),
            [],
            [],
            $headers,
            $requestBody
        );
        return $client->getResponse();
    }

    /**
     * @param string $xml
     * @return \DOMElement
     */
    protected function loadResponse($xml)
    {
        $xmlDom = new \DOMDocument();
        $xmlDom->loadXML($xml);

        $xmlElements = $xmlDom->getElementsByTagName('SsoResponse');
        static::assertEquals(1, $xmlElements->length, $this->fXml($xml, 'Missing xml root element \'SsoResponse\''));

        return $xmlElements->item(0);
    }

    /**
     * @param string $value
     * @return string
     */
    protected function cdata($value)
    {
        return '<![CDATA[' . $value . ']]>';
    }


    /**
     * @param string $xmlRequest
     * @param string $xmlResponse
     * @param string|null $message
     * @return string
     * @internal param string $xml
     */
    protected function fXml($xmlRequest, $xmlResponse, $message = null)
    {
        return (null !== $message ? $message . PHP_EOL : '') .
        'Request: ' . $this->formatXml($xmlRequest) . PHP_EOL .
        'Response: ' . $this->formatXml($xmlResponse) . PHP_EOL;
    }

    /**
     * @param string $xml
     * @return string
     */
    private function formatXml($xml)
    {
        try {
            $dom = new \DOMDocument();
            $dom->loadXML($xml);
            $dom->formatOutput = true;
            return $dom->saveXML();
        } catch (\Exception $exception) {
            return $xml;
        }
    }

    /**
     * Set up test case
     */
    public function setUp()
    {
        parent::setUp();
        $this->configuration = new Configuration(
            sys_get_temp_dir(),
            '/',
            $this->ServiceToken,
            $this->idpTestUsername
        );
        $this->configuration->setUserIdentifier($this->idpUserIdentifier);
        $this->client = static::createClient();
        $this->helperFactory = new HelperFactory($this->configuration, $this->client);
    }
}
