<?php
namespace nulib\ldap;


class names {
  static function split_dn(string $dn, ?string &$rdn, ?string &$parent_dn): bool {
    $dparts = ldap_explode_dn($dn, 0);
    $count = $dparts["count"];
    if ($count > 0) {
      $rdn = $dparts[0];
      $sparts = [];
      for ($i = 1; $i < $count; $i++) {
        $sparts[] = $dparts[$i];
      }
      $parent_dn = implode(",", $sparts);
      return true;
    }
    return false;
  }

  static function ldap_unescape($string) {
    $hex2bin = function ($ms) {
      $m = array_shift($ms);
      return hex2bin(substr($m, 1));
    };
    return preg_replace_callback('/\\\\[0-9a-fA-F]{2}/', $hex2bin, $string);
  }

  static function split_rdn(string $rdn): array {
    $attrs = [];
    $rparts = explode("+", $rdn);
    foreach ($rparts as $rpart) {
      if (strpos($rpart, "=") === false) {
        throw ValueException::invalid_value($rdn, "rdn");
      }
      [$name, $value] = explode("=", $rpart, 2);
      $name = self::ldap_unescape($name);
      $value = self::ldap_unescape($value);
      $attrs[$name][] = $value;
    }
    return $attrs;
  }

  static function build_rdn(string $name, string $value): string {
    $name = ldap_escape($name, 0, LDAP_ESCAPE_DN);
    $value = ldap_escape($value, 0, LDAP_ESCAPE_DN);
    return "$name=$value";
  }

  static function get_dn_names(?string $dn, ?array $lkeys2names=null): ?array {
    $dn_names = null;
    if ($dn !== null) {
      $dn_names = [];
      if (self::split_dn($dn, $rdn, $parent_dn)) {
        foreach (array_keys(self::split_rdn($rdn)) as $name) {
          $dn_names[] = A::get($lkeys2names, strtolower($name), $name);
        }
      }
    }
    return $dn_names;
  }

  static function join($rdn, string $parent_dn): string {
    if (is_array($rdn)) {
      $rparts = [];
      foreach ($rdn as $name => $values) {
        $name = ldap_escape($name, 0, LDAP_ESCAPE_DN);
        foreach (A::with($values) as $value) {
          $value = ldap_escape($value, 0, LDAP_ESCAPE_DN);
          $rparts[] = "$name=$value";
        }
      }
      $rdn = implode("+", $rparts);
    }
    $dparts = [];
    if ($rdn) $dparts[] = $rdn;
    if ($parent_dn) $dparts[] = $parent_dn;
    return implode(",", $dparts);
  }


  /** tester si $dn a le suffixe $suffix */
  static function have_suffix(string $dn, string $suffix): bool {
    $dparts = ldap_explode_dn($dn, 0);
    $sparts = ldap_explode_dn($suffix, 0);
    $count = $sparts["count"];
    return array_slice($dparts, -$count) === array_slice($sparts, -$count);
  }
}
