<?php
namespace nur\v\vp;

use nur\A;
use nur\authz;
use nur\P;
use nur\v\al;
use nur\v\base\TActionSupport;
use nur\v\base\TBasicPage;
use nur\v\model\IBasicPage;
use nur\v\page;

/**
 * Class AInitAuthzPage: une page utilisée pour initialiser l'authentification
 */
class AInitAuthzPage extends AInitPage implements IBasicPage {
  use TBasicPage, TActionSupport;

  /**
   * @var string nom du paramètre qui contient l'action à effectuer.
   * retourner null pour désactiver le support des actions
   */
  const ACTION_PARAM = null;

  /** @var array liste des actions valides */
  const VALID_ACTIONS = null;

  /** @var bool faut-il s'assurer que {@link al} charge la session? */
  const AUTORESTORE_ALERTER_SESSION = true;

  /** @see Html5BasicPageContainer::AUTOCLOSE_SESSION() */
  protected function AUTOCLOSE_SESSION(): ?bool {
    return static::AUTOCLOSE_SESSION;
  } const AUTOCLOSE_SESSION = null;

  /** la connexion SU est-elle autorisée? */
  protected function SULOGIN_ALLOWED(): bool {
    return static::SULOGIN_ALLOWED;
  } const SULOGIN_ALLOWED = false;

  function beforeConfig(array &$config): void {
    parent::beforeConfig($config);
    A::merge_nn($config, [
      "autoclose_session" => $this->AUTOCLOSE_SESSION(),
    ]);
  }

  function beforeSetup(): void {
    parent::beforeSetup();
    if ($this->SULOGIN_ALLOWED()) $this->suloginMaybe();
    if (static::AUTORESTORE_ALERTER_SESSION) {
      # s'assurer que la session est chargée
      al::get()->restoreSession();
    }
  }

  protected function suloginMaybe(): void {
    $username = P::get("su!");
    if ($username) {
      $am = authz::manager();
      $am->setSulogin();
      $am->selectAuthz($username);
      page::redirect();
    }
  }

  protected function ensureAuthOrRedirect(bool $requireAuth, bool $requireAuthz, $requireRole, $requirePerm): void {
    $am = authz::manager();
    $loginUrl = $this->getLoginUrl();
    $destUrl = page::self(true);
    if (!$am->checkCookie()) {
      if (!$requireAuth) return;
      $am->redirect($am::REASON_LOGIN, $destUrl, $loginUrl);
    } elseif (!$am->checkSession()) {
      if ($am->isNewSession()) {
        $am->redirect($am::REASON_LOGIN, $destUrl, $loginUrl);
      } else {
        $am->redirect($am::REASON_SESSION, $destUrl, $loginUrl);
      }
    } elseif ($requireAuth && !$am->isAuth()) {
      $am->redirect($am::REASON_SESSION, $destUrl, $loginUrl);
    }
    A::ensure_narray($requireRole);
    A::ensure_narray($requirePerm);
    if ($requireAuthz && $am->isAuth() && !$am->checkAuthz($requireRole, $requirePerm)) {
      $am->redirect($am::REASON_UNAUTHORIZED, $destUrl, $loginUrl);
    }
    if ($am->isAuth()) $am->setConnected();
  }

  protected function ensureFormLoginAndRedirect(?string $username, ?string $password, string $destUrl): void {
    if ($username === null && $password === null) return;
    if (authz::manager()->formLogin($username, $password)) {
      page::redirect($destUrl);
    }
  }
}
