<?php
namespace nur\passwd;

use nur\b\IllegalAccessException;
use nur\b\ValueException;

class EtuPasswordGenerator {
  const V2 = 2, V3 = 3, V4 = 4;

  function __construct(?int $version=null) {
    if ($version === null) $version = self::V4;
    $this->version = $version;
  }

  private $version;

  function getVersion(): int {
    return $this->version;
  }

  function generate(int $codEtu, ?int $version=null): string {
    if ($version === null) $version = $this->version;
    switch ($version) {
    case self::V2: return $this->generate2($codEtu);
    case self::V3: return $this->generate3($codEtu);
    case self::V4: return $this->generate4($codEtu);
    default: throw ValueException::invalid_value($version, "version");
    }
  }

  private static $generate2_groups;
  static function init_generate2(array $groups): void {
    self::$generate2_groups = $groups;
  }

  protected function generate2(int $codEtu): string {
    $groups = self::$generate2_groups;
    if ($groups == null) {
      throw IllegalAccessException::unexpected_state("init_generate2");
    }
    $pass = "";
    for ($i = 0; $i < 8; $i++) {
      $group = $groups[$i];
      $grouplen = strlen($group);
      $pass .= $group[$codEtu % $grouplen];
    }
    return $pass;
  }

  /** @var PasswordGenerator */
  private $pg;

  /** @var callable */
  private static $gen3seed;

  static function init_gen3seed(callable $seed): void {
    self::$gen3seed = $seed;
  }

  protected function generate3(int $codEtu): string {
    if ($this->pg === null) $this->pg = new PasswordGenerator();
    return $this->pg->generate(3, 1, (self::$gen3seed)($codEtu));
  }

  /** @var callable */
  private static $gen4seed;

  static function init_gen4seed(callable $seed): void {
    self::$gen4seed = $seed;
  }

  protected function generate4(int $codEtu): string {
    if ($this->pg === null) $this->pg = new PasswordGenerator();
    return $this->pg->generate(4, 1, (self::$gen4seed)($codEtu));
  }
}
