<?php

declare(strict_types=1);

namespace PhpWA\Crypto\Signal;

use InvalidArgumentException;

final class SignalRatchet
{
    /** @var string */ private $rootKey;
    /** @var SignalKeyPair */ private $ephemeralKeyPair;
    /** @var string */ private $lastRemoteEphemeralKey;
    /** @var int */ private $previousCounter;

    public function __construct(string $rootKey, SignalKeyPair $ephemeralKeyPair, string $lastRemoteEphemeralKey, int $previousCounter = 0)
    {
        SignalCurve::assertPublicKey($lastRemoteEphemeralKey);
        if (strlen($rootKey) !== 32 || $previousCounter < 0 || $previousCounter > 0xffffffff) {
            throw new InvalidArgumentException('Signal ratchet state is invalid.');
        }
        $this->rootKey = $rootKey;
        $this->ephemeralKeyPair = $ephemeralKeyPair;
        $this->lastRemoteEphemeralKey = $lastRemoteEphemeralKey;
        $this->previousCounter = $previousCounter;
    }

    public function rootKey(): string { return $this->rootKey; }
    public function ephemeralKeyPair(): SignalKeyPair { return $this->ephemeralKeyPair; }
    public function lastRemoteEphemeralKey(): string { return $this->lastRemoteEphemeralKey; }
    public function previousCounter(): int { return $this->previousCounter; }
    public function setRootKey(string $key): void { if (strlen($key) !== 32) { throw new InvalidArgumentException('Signal root key must contain 32 bytes.'); } $this->rootKey = $key; }
    public function setEphemeralKeyPair(SignalKeyPair $pair): void { $this->ephemeralKeyPair = $pair; }
    public function setLastRemoteEphemeralKey(string $key): void { SignalCurve::assertPublicKey($key); $this->lastRemoteEphemeralKey = $key; }
    public function setPreviousCounter(int $counter): void { if ($counter < 0 || $counter > 0xffffffff) { throw new InvalidArgumentException('Signal previous counter is invalid.'); } $this->previousCounter = $counter; }
}
