<?php

namespace iDServer\Message;

use DOMDocument;
use DOMXPath;
use Exception;
use iDServer\AbstractKeyStore;
use iDServer\Constants;
use iDServer\Log;
use iDServer\Message\Strategy\AbstractMessageHandlingStrategy;
use iDServer\Message\Strategy\MixedMessageHandlingStrategy;
use iDServer\Saml\LogoutResponseData;
use iDServer\Saml\Status;


class LogoutResponse extends AbstractMessage
{
    /**
     * @param AbstractKeyStore $keyStore
     * @param LogoutResponseData $data
     */
    public function __construct(AbstractKeyStore $keyStore, LogoutResponseData $data)
    {
        parent::__construct($keyStore, $data);
    }

    /**
     * @return string
     */
    public function getType()
    {
        return MessageType::LOGOUT_REPLY;
    }

    /**
     * Get the DOMDocument instance of the unsigned LogoutResponse XML
     *
     * @param AbstractMessageHandlingStrategy $strategy
     * @return DOMDocument
     */
    protected function getUnsignedXml(AbstractMessageHandlingStrategy $strategy)
    {
        /* @var $data LogoutResponseData */
        $data = $this->getData();
        $doc = $strategy->createLogoutResponse($data);

        Log::debug("Constructed unsigned logout xml:\n" . $doc->saveXML());
        return $doc;
    }

    /**
     * @param AbstractKeyStore $keyStore
     * @param DOMDocument $doc
     * @return array
     *
     *      <ul>
     *          <li>SessionIndex: string, SessionIndex from the XML
     *          <li>NameID: string, NameID from the XML
     *          <li>MessageId: string, ID from the XML
     *          <li>MessageType: string, {@link MessageType::Logout}
     *          <li>XML: DOMDocument,
     *          <li>Response: {@link LogoutResponse}
     *      </ul>
     * @throws Exception
     */
    public static function receiveRequest(AbstractKeyStore $keyStore, DOMDocument $doc)
    {
        Log::debug("Receiving login request.");
        $xpath = new DOMXPath($doc);
        $xpath->registerNamespace('saml2', Constants\NS_SAML);
        $xpath->registerNamespace('saml2p', Constants\NS_SAMLP);

        $sessIndex = $xpath->query("./saml2p:SessionIndex", $doc->documentElement)->item(0)->nodeValue;
        $nameId = $xpath->query("./saml2:NameID", $doc->documentElement)->item(0)->nodeValue;

        $id = $doc->documentElement->getAttribute('ID');

        $data = new LogoutResponseData();
        $data->setId($id);

        $data->setStatus(new Status(Status::SUCCESS));

        $response = new LogoutResponse($keyStore, $data);

        Log::debug("Successfully parsed Logout request " . $id);
        $result = [
            'SessionIndex' => $sessIndex,
            'NameID' => $nameId,
            'MessageId' => $id,
            'MessageType' => MessageType::LOGOUT,
            'XML' => $doc,
            'Response' => $response,
        ];

        $result['Output'] = base64_encode($response->getSignedXml(new MixedMessageHandlingStrategy())->saveXML());

        return $result;
    }
}
