<?php
namespace Misuzu\Auth;

class AuthTokenInfo {
    // Standard auth token properties
    // Props may be used for general purpose stuff not defined here but don't use single char names for them
    public const USER_ID = 'u'; // User ID
    public const SESSION_TOKEN = 's'; // Session token
    public const SESSION_TOKEN_HEX = 't'; // Session token that should be hex encoded
    public const IMPERSONATED_USER_ID = 'i'; // Impersonated user ID

    public function __construct(
        private int $timestamp = 0,
        private array $props = []
    ) {}

    public function isEmpty(): bool {
        return $this->timestamp === 0 && empty($this->props);
    }

    public function getTimestamp(): int {
        return $this->timestamp;
    }

    public function getProperties(): array {
        return $this->props;
    }

    public function toBuilder(): AuthTokenBuilder {
        return new AuthTokenBuilder($this);
    }

    public function hasProperty(string $name): bool {
        return array_key_exists($name, $this->props);
    }

    public function getProperty(string $name): string {
        return $this->props[$name] ?? '';
    }

    public function hasUserId(): bool {
        return $this->hasProperty(self::USER_ID);
    }

    public function getUserId(): string {
        return $this->getProperty(self::USER_ID);
    }

    public function hasSessionToken(): bool {
        return $this->hasProperty(self::SESSION_TOKEN)
            || $this->hasProperty(self::SESSION_TOKEN_HEX);
    }

    public function getSessionToken(): string {
        if($this->hasProperty(self::SESSION_TOKEN))
            return $this->getProperty(self::SESSION_TOKEN);

        if($this->hasProperty(self::SESSION_TOKEN_HEX))
            return bin2hex($this->getProperty(self::SESSION_TOKEN_HEX));

        return '';
    }

    public function hasImpersonatedUserId(): bool {
        return $this->hasProperty(self::IMPERSONATED_USER_ID);
    }

    public function getImpersonatedUserId(): string {
        return $this->getProperty(self::IMPERSONATED_USER_ID);
    }

    private static AuthTokenInfo $empty;

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

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

AuthTokenInfo::init();
