<?php
namespace Misuzu\Auth;

use Misuzu\Auth\SessionInfo;
use Misuzu\Users\UserInfo;

class AuthInfo {
    private AuthTokenInfo $tokenInfo;
    private ?UserInfo $userInfo;
    private ?SessionInfo $sessionInfo;
    private ?UserInfo $realUserInfo;

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

    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;
    }

    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;
    }

    private static AuthInfo $empty;

    public static function init(): void {
        self::$empty = new AuthInfo(AuthTokenInfo::empty());
    }

    public static function empty(): self {
        return self::$empty;
    }
}

AuthInfo::init();
