<?php


namespace Mainto\RpcServer\Util\Net\Conn;


use FFI;
use Mainto\RpcServer\Util\Bytes\Buffer;
use Mainto\RpcServer\Util\Bytes\Bytes;
use Mainto\RpcServer\Util\Net\Address;
use Mainto\RpcServer\Util\Net\Conn;

class FastMQConn implements Conn {

    /**
     * @var mixed
     */
    private $mq;
    private string $address;

    private Buffer $buf;

    public function __construct (string $address, $mq) {
        $this->mq = $mq;
        $this->address = $address;
        $this->buf = Bytes::newBuffer();
    }

    public static function newConnByAddress($address) {
        $mq = FFI::cdef(<<<EOF
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
char* openMQ(char* p0);

char* read(char* p0, int p1);

GoString readPackage(char* p0);

char* write(char* p0, char* p1);
EOF, __DIR__.'/../../../Util/FastMQ/libdemo.so');
        $res = $mq->openMQ($address);
        if (FFI::string($res) != "ok") {
            dump($res);
            throw new \RuntimeException($res);
        }
        $instance = new self($address, $mq);

        $instance->write("connect");

        return $instance;
    }

    public function close () {
    }

    public function localAddr (): Address {
    }

    public function remoteAddr (): Address {
    }

    public function read (int $size): ?string {
        if ($this->buf->empty()) {
            $this->buf->reset();

            $d = $this->mq->readPackage($this->address);
            dump($d);
            $w = FFI::string($d);
            dump('w');
            dump($w);
            $this->buf->write($w);
        }

        $res = $this->buf->read($size);
        dump($res);
        return $res;
    }

    public function write (string $p): int {
        dump(1);
        $res = $this->mq->write($this->address, $p);
        //todo $res
        dump(2);

        return strlen($p);
    }
}