<?php
namespace nur\v\model;

/**
 * Interface IRouteManager: interface pour un gestionnaire de routes
 */
interface IRouteManager {
  /** @var int indique que la correspondance du chemin doit être exacte */
  const MODE_EXACT = 0;

  /**
   * @var int indique que la correspondance du chemin se fait sur le préfixe
   * par exemple:
   * - 'index.php' matche 'index.php' et 'index.php/suffix'
   * - 'path/to/' matche 'path/to/index.php' et 'path/to/menu.php'",
   * si le chemin ne se termine pas par '/', une correspondance exacte est
   * automatiquement rajoutée
   * contraiement à {@link MODE_PACKAGE}, quel que soit le chemin matché, c'est
   * toujours la même page qui prend en charge le chemin
   */
  const MODE_PREFIX = 1;

  /**
   * @var int indique que la correspondance du chemin se fait sur le préfixe, et
   * que la classe associée est calculée automatiquement en cherchant à partir
   * d'un package spécifié. par exemple:
   * - si on a [path]="prefix/" et [page]="package\\Class"
   * - alors 'prefix/index.php' est pris en charge par package\IndexPage
   * - et 'prefix/sub/do-it.php' est pris en charge par package\sub\DoItPage
   * si le chemin ne se termine pas par '/', une correspondance exacte est
   * automatiquement rajoutée
   */
  const MODE_PACKAGE = 2;

  /**
   * @var int comme {@link MODE_PACKAGE} mais en utilisant '--' au lieu de '/'
   */
  const MODE_PACKAGE2 = 3;

  const ROUTE_SCHEMA = [
    "path" => [null, null, "chemin vers la page", "required" => true],
    "page" => [null, null, "classe ou instance de IPage associée", "required" => true],
    "mode" => [null, self::MODE_EXACT, "mode de correspondance du chemin"],
    "aliases" => [null, null, "ensemble de chemins qui sont des aliases de path",
      "help" => "la correspondance sur les aliases est toujours exacte, quel que soit le mode sélectionné",
    ],
    "cons_args" => [null, null, "(interne) arguments pour instancier la classe"],
    "package" => [null, null, "(interne) package correspondant à [page]"],
  ];

  /**
   * ajouter une nouvelle route. $routes est une liste d'éléments conformes au
   * schéma {@link ROUTE_SCHEMA}
   */
  function addRoute(array ...$routes): void;

  /**
   * spécifier la page par défaut si aucune route ne correspond
   *
   * @param string|IPage|array
   */
  function setErrorPage($page);

  /**
   * obtenir une instance de {@link IPage} correspondant au chemin spécifié e.g
   * '/index.php'
   *
   * si $path===null, prendre le chemin courant i.e "$php_self.$path_info"
   */
  function getPage(?string $path=null): IPage;

  /**
   * obtenir le chemin correspondant à la page spécifiée.
   *
   * $page peut être une classe qui implémente {@link IPage} ou une instance de
   * {@link IPage}
   */
  function getPath($page): string;
}
