<?php
namespace App\Controller;
 
use App\Entity\ltirequest;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;

use OAT\Library\Lti1p3Core\Message\Launch\Builder\PlatformOriginatingLaunchBuilder;
use OAT\Library\Lti1p3Core\Message\LtiMessageInterface;
use OAT\Library\Lti1p3Core\Message\Payload\Claim\ContextClaim;
use OAT\Library\Lti1p3Core\Registration\RegistrationRepositoryInterface;
use OAT\Library\Lti1p3Core\Resource\LtiResourceLink\LtiResourceLink;
use OAT\Library\Lti1p3Core\Registration\Registration;
use OAT\Library\Lti1p3Core\Platform\Platform;
use OAT\Library\Lti1p3Core\Tool\Tool;
use OAT\Library\Lti1p3Core\Security\Key\KeyChain;
use OAT\Library\Lti1p3Core\Security\Key\Key;
use OAT\Library\Lti1p3Core\Message\Launch\Builder\LtiResourceLinkLaunchRequestBuilder;
use OAT\Library\Lti1p3Core\Security\User\UserAuthenticatorInterface;
use OAT\Library\Lti1p3Core\Security\Oidc\OidcAuthenticator;
use OAT\Library\Lti1p3Core\Security\Oidc\OidcInitiator;
use OAT\Library\Lti1p3Core\Security\User;
use OAT\Library\Lti1p3Core\User\UserIdentity;

use Nyholm\Psr7\Factory\Psr17Factory;
use Psr\Http\Message\ServerRequestInterface;

#[AsController]
class LtiRequestController extends AbstractController
{
    private $repo;
    private $builder;
    private $userAuthenticator;

    public function __construct(RegistrationRepositoryInterface $repo, LtiResourceLinkLaunchRequestBuilder $builder)
    {
        $this->repo = $repo;
        $this->builder = $builder;
    }

    public function __invoke(string $learnerid)
    {
        $registration = $this->repo->find('local');

        $ltiResourceLink = new LtiResourceLink(
            'resourceLinkIdentifier', //needs to be unique
            [
                'url' => 'http://127.0.0.1:8001/tool/launch',
                'title' => 'LTI Resource Link'
            ]
        );

        $message = $this->builder->buildLtiResourceLinkLaunchRequest(
            $ltiResourceLink,
            $registration,
            'loginHint'
        );

        // 1 + 2
        $oidcInitiator = new OidcInitiator($this->repo);
        $oidcInitiationResult = $oidcInitiator->initiate($this->createServerRequest('GET', $message->toUrl()));
      
        // 3 + 4
        // Perform the login authentication (delegating to the $userAuthenticator with the hint 'loginHint') 
        $userAuthenticator = new UserAuthenticator(true, true); // TESTING ONLY, 2nd param needs to be false
        $oidcAuthenticator = new OidcAuthenticator($this->repo, $userAuthenticator);
        //dump($oidcAuthenticator);

        $oidcAuthenticationResult = $oidcAuthenticator->authenticate($this->createServerRequest('GET', $oidcInitiationResult->toUrl()));      
        //dump($oidcAuthenticationResult);
        
        // Auto redirection to the tool via the user's browser
        //return new Response($oidcAuthenticationResult->toHtmlRedirectForm());

        //return URL to caller for auto re-direction via the user's browser
        return new Response(json_encode($oidcAuthenticationResult->toUrl()));
    }

    private function createServerRequest(string $method, string $uri, array $params = [], array $headers = []): ServerRequestInterface 
    {
        $serverRequest =  (new Psr17Factory())->createServerRequest($method, $uri);

        foreach ($headers as $headerName => $headerValue) {
            $serverRequest = $serverRequest->withAddedHeader($headerName, $headerValue);
        }

        $method = strtoupper($method);

        if ($method === 'GET') {
            return $serverRequest->withQueryParams($params);
        }

        if ($method === 'POST') {
            return $serverRequest->withParsedBody($params);
        }

        return $serverRequest;
    }
}