<?php
namespace nur\data\expr;

use nur\A;
use nur\b\coll\BaseArray;
use nur\config;
use nur\func;
use nur\session;

class SimpleContext extends BaseArray implements IContext {
  /**
   * @return array une liste de sources {$name => $source} conformes au schéma
   * {@link IContext::SOURCE_SCHEMA}
   */
  protected function SOURCES(): array {
    return static::SOURCES;
  } const SOURCES = [];

  /**
   * @return array une liste d'expressions {$name => $expr} conformes au schéma
   * {@link IContext::EXPR_SCHEMA}
   */
  protected function EXPRS(): array {
    return static::EXPRS;
  } const EXPRS = [];

  /**
   * @return array une liste de conditions {$key => $cond} conformes au schéma
   * {@link IContext::COND_SCHEMA}
   */
  protected function CONDS(): array {
    return static::CONDS;
  } const CONDS = [];

  /** @var mixed l'objet sur lequel sont appliquées les appels de méthode */
  protected $object;

  function __construct(?array $data=null) {
    parent::__construct($data);
    $this->object = $this;
  }

  function getContextInfos(): array {
    return [
      "sources" => $this->SOURCES(),
      "exprs" => $this->EXPRS(),
      "conds" => $this->CONDS(),
    ];
  }

  function getValue(string $pkey) {
    #XXX parcourir les sources
    return A::pget($this->data, $pkey);
  }

  function getSession(string $pkey) {
    return session::pget($pkey);
  }

  function getConfig(string $pkey) {
    return config::get($pkey);
  }

  function callMethod($method) {
    func::ensure_func($method, $this->object, $args);
    return func::call($method, ...$args);
  }

  ## ArrayAccess
  function has($key): bool { return $this->_has($key); }
  function &get($key, $default=null) { return $this->_get($key, $default); }
  function set($key, $value): self { return $this->_set($key, $value); }
  function add($value): self { return $this->_set(null, $value); }
  function del($key): self { return $this->_del($key); }
}