<?php


namespace Mainto\RpcServer\Util\Bytes;


use Mainto\RpcServer\Util\IO\Reader;
use Mainto\RpcServer\Util\IO\ReaderFrom;
use Mainto\RpcServer\Util\IO\ReadWriter;
use Mainto\RpcServer\Util\IO\Writer;
use Mainto\RpcServer\Util\IO\WriterTo;
use RuntimeException;

class Buffer implements WriterTo, ReadWriter, ReaderFrom {
    private string $buf = "";
    private int $offset = 0;

    public function writeByte (string $byte) {
        $this->buf .= $byte;
    }

    public function writeString (string $string) {
        $this->buf .= $string;
    }

    public function writeTo (Writer $w): int {
        return $w->write($this->bytes());
    }

    public function reset() {
        $this->offset = 0;
        $this->buf= "";
    }

    public function write (string $p): int {
        $this->buf .= $p;

        return strlen($p);
    }

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

    public function empty(): bool {
        return $this->offset >= strlen($this->buf);
    }

    public function read (int $size): ?string {
        if ($this->empty()) {
            return null;
        }

        $read = substr($this->buf, $this->offset, $size);

        $this->offset += strlen($read);

        return $read;
    }

    public function readFrom (Reader $r): int {
        $n = 0;

        while (true) {
            $read = $r->read(Bytes::MinRead);
            if ($read === null) {
                break;
            }

            if (strlen($read) < 0) {
                throw new RuntimeException("bytes.Buffer: reader returned negative count from Read");
            }

            $this->buf .= $read;

            $n += strlen($read);
        }

        return $n;
    }

    public function len () {
        return strlen($this->buf);
    }
}