<?php

namespace AuthStack\SAMLServiceProvider\Model;

use LightSaml\Helper;
use LightSaml\SamlConstants;
use LightSaml\Binding\AbstractBinding;
use LightSaml\Binding\HttpPostBinding;
use LightSaml\Binding\HttpRedirectBinding;
use LightSaml\Context\Profile\MessageContext;
use AuthStack\SAMLServiceProvider\Exceptions\SAMLException;

class LogoutResponse
{
    /**
     * @var \LightSaml\Model\Protocol\LogoutRequest
     */
    protected $request;

    /**
     * @var ServiceProvider
     */
    protected $sp;

    /**
     * @var IdentityProvider
     */
    protected $idp;

    /**
     * LogoutResponse constructor.
     * @param \LightSaml\Model\Protocol\LogoutRequest $response
     * @param ServiceProvider $sp
     * @param IdentityProvider $idp
     */
    public function __construct(\LightSaml\Model\Protocol\LogoutRequest $request, ServiceProvider $sp, IdentityProvider $idp)
    {
        $this->request = $request;
        $this->sp = $sp;
        $this->idp = $idp;

        $this->create();
    }

    /**
     * @return \LightSaml\Model\Protocol\LogoutResponse
     */
    public function getLogoutRequest(): \LightSaml\Model\Protocol\LogoutRequest
    {
        return $this->request;
    }

    /**
     * @throws SAMLException
     */
    public function send()
    {
        switch($this->idp->getLogoutBinding())
        {
            case SamlConstants::BINDING_SAML2_HTTP_POST:
                $this->sendWith(new HttpPostBinding());
                break;

            case SamlConstants::BINDING_SAML2_HTTP_REDIRECT:
                $this->sendWith(new HttpRedirectBinding());
                break;

            default:
                throw new SAMLException(sprintf("Unsupported binding: ", $this->idp->getLogoutBinding()), 500);
                break;
        }
    }

    /**
     *
     */
    protected function create(): void
    {
        $logout = new \LightSaml\Model\Protocol\LogoutResponse();

        $logout
            ->setInResponseTo($this->request->getID())
            ->setID(Helper::generateID())
            ->setDestination($this->idp->getLogoutURL())
            ->setIssueInstant(time())
            ;

        if($this->idp->wantsSignedReguests())
        {
            $logout->setSignature($this->sp->getSignatureWriter());
        }

        $this->response = $logout;
    }

    /**
     * @param AbstractBinding $binding
     */
    protected  function sendWith(AbstractBinding $binding)
    {
        $request = $this->getLogoutRequest();

        $context = new MessageContext();

        $context->setMessage($request);

        $binding->send($context)->send();
    }
}