<?php

declare(strict_types=1);

namespace PhpWA\Auth;

use InvalidArgumentException;
use PhpWA\Crypto\PreKeyFactory;
use PhpWA\Protocol\Jid\Jid;

final class SignalIdentity
{
    /** @var string */ private $name;
    /** @var int */ private $deviceId;
    /** @var string */ private $identifierKey;

    public function __construct(string $name, int $deviceId, string $identifierKey)
    {
        $jid = Jid::parse($name);
        if (!$jid instanceof Jid || (!$jid->isLid() && !$jid->isHostedLid())
            || preg_match('/^[1-9][0-9]{0,19}$/D', $jid->user()) !== 1) {
            throw new InvalidArgumentException('Signal identity name must be a numeric LID JID.');
        }
        if ($deviceId < 0 || $deviceId > 255 || strlen($identifierKey) !== 33 || $identifierKey[0] !== "\x05") {
            throw new InvalidArgumentException('Signal identity address or key is invalid.');
        }
        $this->name = $name;
        $this->deviceId = $deviceId;
        $this->identifierKey = $identifierKey;
    }

    public static function fromAccountSignatureKey(string $lid, string $accountSignatureKey): self
    {
        return new self($lid, 0, PreKeyFactory::signalPublicKey($accountSignatureKey));
    }

    public function name(): string { return $this->name; }
    public function deviceId(): int { return $this->deviceId; }
    public function identifierKey(): string { return $this->identifierKey; }

    /** @return array{name:string,device_id:int,identifier_key:string} */
    public function exportState(): array
    {
        return [
            'name' => $this->name,
            'device_id' => $this->deviceId,
            'identifier_key' => base64_encode($this->identifierKey),
        ];
    }

    public function equals(self $other): bool
    {
        return $this->deviceId === $other->deviceId
            && hash_equals($this->name, $other->name)
            && hash_equals($this->identifierKey, $other->identifierKey);
    }
}
