<?php
namespace Misuzu\Auth;

use Index\DateTime;
use Index\Data\IDbResult;
use Index\Net\IPAddress;
use Misuzu\ClientInfo;

class SessionInfo {
    private string $id;
    private string $userId;
    private string $token;
    private string $firstRemoteAddr;
    private ?string $lastRemoteAddr;
    private string $userAgent;
    private string $clientInfo;
    private string $countryCode;
    private int $expires;
    private bool $bumpExpires;
    private int $created;
    private ?int $lastActive;

    public function __construct(IDbResult $result) {
        $this->id = (string)$result->getInteger(0);
        $this->userId = (string)$result->getInteger(1);
        $this->token = $result->getString(2);
        $this->firstRemoteAddr = $result->getString(3);
        $this->lastRemoteAddr = $result->isNull(4) ? null : $result->getString(4);
        $this->userAgent = $result->getString(5);
        $this->clientInfo = $result->getString(6);
        $this->countryCode = $result->getString(7);
        $this->expires = $result->getInteger(8);
        $this->bumpExpires = $result->getInteger(9) !== 0;
        $this->created = $result->getInteger(10);
        $this->lastActive = $result->isNull(11) ? null : $result->getInteger(11);
    }

    public function getId(): string {
        return $this->id;
    }

    public function getUserId(): string {
        return $this->userId;
    }

    public function getToken(): string {
        return $this->token;
    }

    public function getFirstRemoteAddressRaw(): string {
        return $this->firstRemoteAddr;
    }

    public function getFirstRemoteAddress(): IPAddress {
        return IPAddress::parse($this->firstRemoteAddr);
    }

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

    public function getLastRemoteAddressRaw(): string {
        return $this->lastRemoteAddr;
    }

    public function getLastRemoteAddress(): ?IPAddress {
        return $this->lastRemoteAddr === null ? null : IPAddress::parse($this->lastRemoteAddr);
    }

    public function getUserAgentString(): string {
        return $this->userAgent;
    }

    public function getClientInfoRaw(): string {
        return $this->clientInfo;
    }

    public function getClientInfo(): ClientInfo {
        return ClientInfo::decode($this->clientInfo);
    }

    public function getCountryCode(): string {
        return $this->countryCode;
    }

    public function getExpiresTime(): int {
        return $this->expires;
    }

    public function getExpiresAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->expires);
    }

    public function shouldBumpExpires(): bool {
        return $this->bumpExpires;
    }

    public function hasExpired(): bool {
        return $this->expires < time();
    }

    public function getCreatedTime(): int {
        return $this->created;
    }

    public function getCreatedAt(): DateTime {
        return DateTime::fromUnixTimeSeconds($this->created);
    }

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

    public function getLastActiveTime(): ?int {
        return $this->lastActive;
    }

    public function getLastActiveAt(): ?DateTime {
        return $this->lastActive === null ? null : DateTime::fromUnixTimeSeconds($this->lastActive);
    }
}
