<?php

declare(strict_types=1);

namespace PhpWA\Protocol\Binary;

use PhpWA\Exception\ProtocolException;

final class BinaryWriter
{
    /** @var string */ private $buffer = '';
    /** @var int */ private $limit;

    public function __construct(int $limit)
    {
        $this->limit = $limit;
    }

    public function byte(int $value): void
    {
        $this->append(chr($value & 0xff));
    }

    public function integer(int $value, int $bytes): void
    {
        if ($value < 0 || $bytes < 1 || $bytes > 4) {
            throw new ProtocolException('Invalid WABinary integer write.');
        }
        for ($index = $bytes - 1; $index >= 0; $index--) {
            $this->byte(($value >> ($index * 8)) & 0xff);
        }
    }

    public function integer20(int $value): void
    {
        if ($value < 0 || $value >= 1048576) {
            throw new ProtocolException('Invalid WABinary 20-bit integer.');
        }
        $this->byte(($value >> 16) & 0x0f);
        $this->byte(($value >> 8) & 0xff);
        $this->byte($value & 0xff);
    }

    public function append(string $bytes): void
    {
        if (strlen($this->buffer) + strlen($bytes) > $this->limit) {
            throw new ProtocolException('Encoded WABinary frame exceeds configured limit.');
        }
        $this->buffer .= $bytes;
    }

    public function bytes(): string
    {
        return $this->buffer;
    }
}
