<?php

namespace Authstack\OpenIDConnect;

use Assert\Assertion;

class Provider
{
    protected $iss;
    protected $authEndpoint;
    protected $tokenEndpoint;
    protected $userInfoEndpoint;
    protected $cert;
    protected $secret; // For HMAC signatures

    public function __construct(string $iss, string $authorizationEndpoint, ?string $certificate = null, ?string $tokenEndpoint = null, ?string $userInfoEndpoint = null)
    {
        $this->iss = $iss;
        $this->authEndpoint = $authorizationEndpoint;
        $this->cert = $certificate;
        $this->tokenEndpoint = $tokenEndpoint;
        $this->userInfoEndpoint = $userInfoEndpoint;
    }

    /**
     * @param array $data
     * @return Provider
     */
    public static function create(array $data): self
    {
        Assertion::keyIsset($data, 'iss', 'Required key "iss" (issuer) not set');
        Assertion::keyIsset($data, 'authorizationEndpoint', 'Required key "authorizationEndpoint" not set');

        $me = new static($data['iss'], $data['authorizationEndpoint']);

        if(isset($data['certificate']))
        {
            $me->setCertificate($data['certificate']);
        }

        if(isset($data['secret']))
        {
            $me->setHMACSecret($data['secret']);
        }

        if(isset($data['tokenEndpoint']))
        {
            $me->setTokenEndpoint($data['tokenEndpoint']);
        }

        if(isset($data['userInfoEndpoint']))
        {
            $me->setUserInfoEndpoint($data['userInfoEndpoint']);
        }

        return $me;
    }

    /**
     * @return string
     */
    public function getIssuer(): string
    {
        return $this->iss;
    }

    /**
     * @param string $cert
     * @return Provider
     */
    public function setCertificate(string $cert): self
    {
        Assertion::isArray(@openssl_x509_parse($cert));

        $this->cert = $cert;

        return $this;
    }

    /**
     * @return string
     */
    public function getCertificate(): string
    {
        return $this->cert;
    }

    /**
     * @param string $secret
     * @return Provider
     */
    public function setHMACSecret(string $secret): self
    {
        $this->secret = $secret;

        return $this;
    }

    /**
     * @return string
     */
    public function getHMACSecret(): string
    {
        return $this->secret;
    }

    /**
     * @param string $endpoint
     * @return Provider
     */
    public function setAuthEndpoint(string $endpoint): self
    {
        $this->authEndpoint = $endpoint;

        return $this;
    }

    /**
     * @return string
     */
    public function getAuthEndpoint(): string
    {
        return $this->authEndpoint;
    }

    /**
     * @param string $endpoint
     * @return Provider
     */
    public function setTokenEndpoint(string $endpoint): self
    {
        $this->tokenEndpoint = $endpoint;

        return $this;
    }

    /**
     * @return null|string
     */
    public function getTokenEndpoint(): ?string
    {
        return $this->tokenEndpoint;
    }

    /**
     * @param string $endpoint
     * @return Provider
     */
    public function setUserInfoEndpoint(string $endpoint): self
    {
        $this->userInfoEndpoint = $endpoint;

        return $this;
    }

    /**
     * @return null|string
     */
    public function getUserInfoEndpoint(): ?string
    {
        return $this->userInfoEndpoint;
    }
}