<?php
namespace Misuzu\Auth;

use Index\XArray;
use Misuzu\Auth\SessionInfo;
use Misuzu\Forum\ForumCategoryInfo;
use Misuzu\Perms\IPermissionResult;
use Misuzu\Perms\Permissions;
use Misuzu\Users\UserInfo;

class AuthInfo {
    private Permissions $permissions;
    private AuthTokenInfo $tokenInfo;
    private ?UserInfo $userInfo;
    private ?SessionInfo $sessionInfo;
    private ?UserInfo $realUserInfo;
    private array $perms;

    public function __construct(Permissions $permissions) {
        $this->permissions = $permissions;
        $this->setInfo(AuthTokenInfo::empty());
    }

    public function setInfo(
        AuthTokenInfo $tokenInfo,
        ?UserInfo $userInfo = null,
        ?SessionInfo $sessionInfo = null,
        ?UserInfo $realUserInfo = null
    ): void {
        $this->tokenInfo = $tokenInfo;
        $this->userInfo = $userInfo;
        $this->sessionInfo = $sessionInfo;
        $this->realUserInfo = $realUserInfo;
        $this->perms = [];
    }

    public function removeInfo(): void {
        $this->setInfo(AuthTokenInfo::empty());
    }

    public function getTokenInfo(): AuthTokenInfo {
        return $this->tokenInfo;
    }

    public function isLoggedIn(): bool {
        return $this->userInfo !== null;
    }

    public function getUserId(): ?string {
        return $this->userInfo?->getId();
    }

    public function getUserInfo(): ?UserInfo {
        return $this->userInfo;
    }

    public function getSessionId(): ?string {
        return $this->sessionInfo?->getId();
    }

    public function getSessionInfo(): ?SessionInfo {
        return $this->sessionInfo;
    }

    public function isImpersonating(): bool {
        return $this->realUserInfo !== null;
    }

    public function getRealUserId(): ?string {
        return $this->realUserInfo?->getId();
    }

    public function getRealUserInfo(): ?UserInfo {
        return $this->realUserInfo;
    }

    public function getPerms(
        string $category,
        ForumCategoryInfo|string|null $forumCategoryInfo = null
    ): IPermissionResult {
        $cacheKey = $category;
        if($forumCategoryInfo !== null)
            $cacheKey .= '|' . ($forumCategoryInfo instanceof ForumCategoryInfo ? $forumCategoryInfo->getId() : $forumCategoryInfo);

        if(array_key_exists($cacheKey, $this->perms))
            return $this->perms[$cacheKey];

        return $this->perms[$cacheKey] = $this->permissions->getPermissions($category, $this->userInfo, $forumCategoryInfo);
    }
}
