<?php


namespace Mainto\RpcServer\Util\Net\Listener;


use Mainto\RpcServer\Util\Net\Address;
use Mainto\RpcServer\Util\Net\Conn;
use Mainto\RpcServer\Util\Net\Listener;
use RuntimeException;

class UnixListener implements Listener {
    private Address\UnixAddress $address;
    /**
     * @var false|resource
     */
    private $listenSocket;

    public function __construct (string $address) {
        $listenSocket = @socket_create( AF_UNIX, SOCK_STREAM, 0 );

        if ($listenSocket === false) {
            throw new RuntimeException("create server [$address] error socket is false");
        }

        if (!@socket_bind($listenSocket, $address)) {
            throw new RuntimeException("bind server [$address] error: ". socket_last_error($listenSocket));
        }

        @socket_listen($listenSocket);

        $this->address = new Address\UnixAddress($address);
        $this->listenSocket = $listenSocket;
    }

    public function close () {
        @socket_close($this->listenSocket);
    }

    public function accept (): Conn {
        $socket = socket_accept($this->listenSocket);

        return new Conn\UnixConn($socket);
    }

    public function address (): Address {
        return $this->address;
    }
}