<?php

/*
 * This file is part of the AuthStack project.
 *
 * (c) Buckhill Ltd <development@buckhill.co.uk>
 *
 * This source file is subject to the Buckhill license that is bundled
 * with this source code in the file LICENSE.
 */

namespace AuthStack\SP\Requests;

use LightSaml\Helper;
use LightSaml\SamlConstants;
use LightSaml\Model\Protocol\AuthnRequest;
use LightSaml\Model\Protocol\NameIDPolicy;

class AuthN extends AbstractRequest
{
    protected $authn;
    protected $request_id;

    public function initiate()
    {
        $binding = $this->getIDPBinding();

        switch($binding)
        {
            case SamlConstants::BINDING_SAML2_HTTP_POST:
                $this->initiateWithPOST();
                break;

            case SamlConstants::BINDING_SAML2_HTTP_REDIRECT:
                $this->initiateWithGET();
            default:
        }
    }


    /**
     * @return AuthnRequest
     */
    public function getRequest()
    {
        return $this->getAuthN();
    }

    /**
     * @return AuthnRequest
     */
    public function getAuthN()
    {
        return $this->authn;
    }


    /**
     * @return null|string
     */
    public function getDestination()
    {
        return $this->getAuthN()->getDestination();
    }


    /**
     * @return $this
     */
    protected function create()
    {
        $authn = new AuthnRequest();

        $request_id = Helper::generateID();

        $authn
            ->setNameIDPolicy($this->getNameIdPolicy())
            ->setAssertionConsumerServiceURL($this->getACS())
            ->setProtocolBinding($this->getProtocolBinding())
            ->setID($request_id)
            ->setIssueInstant(new \DateTime("now", new \DateTimeZone("UTC")))
            ->setDestination($this->getSSODestination())
            ->setIssuer($this->getIssuer())
        ;

        if($this->IdPWantsSignedRequests())
        {
            $authn->setSignature($this->getSignature());
        }

        $this->authn = $authn;

        $this->request_id = $authn;

        return $this;
    }


    /**
     * @return NameIDPolicy
     */
    protected function getNameIdPolicy()
    {
        $nameid = new NameIDPolicy(
            \Buckhill\config('AuthStack.SP.nameIdFormat', SamlConstants::NAME_ID_FORMAT_NONE),
            true
        );

        return $nameid;
    }


    /**
     * @return string
     */
    protected function getACS()
    {
        return sprintf("%s%s", \Buckhill\config('AuthStack.baseUrl'), \Buckhill\config('AuthStack.SP.AssertionConsumerService.location'));
    }


    /**
     * @return string
     */
    protected function getProtocolBinding()
    {
        return \Buckhill\config('AuthStack.SP.AssertionConsumerService.binding');
    }


    /**
     * @return string
     */
    protected function getSSODestination()
    {
        return \Buckhill\config(sprintf('AuthStack.IdP.%s.SSO.url', $this->idp));
    }

    /**
     * @return string
     */
    protected function getIDPBinding()
    {
        $idpBinding = null;

        $idpBinding = \Buckhill\config(sprintf('AuthStack.IdP.%s.SSO.binding', $this->idp));

        if(empty($idpBinding))
        {
          throw new \Exception('Could not find SSO binding for the selected IDP in the configuration - check your configuration.');
        }

        return $idpBinding;
    }

}
