<?php
namespace nur\b\authnz;

use ArrayAccess;
use nur\A;
use nur\b\coll\TBaseArray;
use nur\b\coll\TGenericArray;
use nur\str;

class SimpleUser implements IAuthzUser, ArrayAccess {
  use TBaseArray, TGenericArray;

  const SCHEMA = SimpleUserManager::USER_SCHEMA;

  function __construct($data) {
    $this->data = $data;
  }

  function __sleep(): array {
    return ["data"];
  }

  function isValid(): bool {
    return !$this->data["disabled"];
  }
  
  function getUsername(): string {
    return $this->data["username"];
  }
  
  function validatePassword(string $password): bool {
    return $password === $this->data["password"];
  }
  
  function getDisplayName(): ?string {
    $display_name = $this->data["display_name"];
    if ($display_name === null) $display_name = $this->data["username"];
    return $display_name;
  }
  
  function getShortName(): ?string {
    $short_name = $this->data["short_name"];
    if ($short_name === null) $short_name = $this->data["username"];
    return $short_name;
  }

  function getMail(): ?string {
    return $this->data["mail"];
  }

  function getRole(): ?string {
    return $this->data["role"];
  }

  function isRole($roles): bool {
    if ($roles === null) return true;
    $myrole = $this->getRole();
    foreach (A::with($roles) as $role) {
      switch ($role) {
      case self::ROLE_ANON:
        break;
      case self::ROLE_AUTH:
        return true;
      case self::ROLE_AUTHZ:
        if ($myrole !== null || $this->data["perms"]) return true;
        break;
      default:
        if ($role === $myrole) return true;
        if (str::ends_with(":*", $role)) {
          if (str::starts_with(substr($role, 0, -1), $myrole)) {
            return true;
          }
        }
        break;
      }
    }
    return false;
  }

  function debug_getPerms(): ?array {
    return $this->data["perms"];
  }

  function isPerm($perms): bool {
    if ($perms === null) return true;
    $myperms = $this->data["perms"];
    if ($myperms !== null) {
      if (in_array("*", $myperms)) return true;
      foreach (A::with($perms) as $perm) {
        if (in_array($perm, $myperms)) return true;
        if (str::ends_with(":*", $perm)) {
          $prefix = substr($perm, 0, -1);
          foreach ($myperms as $myperm) {
            if (str::starts_with($prefix, $myperm)) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  function debug_getGroups(): ?array {
    return $this->data["groups"];
  }

  function isGroup($groups): bool {
    if ($groups === null) return true;
    $mygroups = $this->data["groups"];
    if ($mygroups !== null) {
      foreach (A::with($groups) as $group) {
        if (in_array($group, $mygroups)) return true;
      }
    }
    return false;
  }
}