<?php


namespace Mainto\RpcServer\Util\Net\Conn;


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

class TcpConn implements Conn {
    /**
     * Socket
     */
    private $socket;

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

    public static function newConnByAddress($address) {
        ["host" => $host, "port" => $port] = parse_url($address);

        $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

        if (!@socket_connect($socket, $host, $port)) {
            throw new RuntimeException("connect to {$host}:{$port} error");
        }

        return new self($socket);
    }

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

    public function read (int $size): ?string {
        $res = socket_read($this->socket, $size);
        if ($res === false || $res === "") {
            throw new RuntimeException(sprintf("socket read [%s] error: ".socket_last_error($this->socket), $res === false ? 'false' : 'empty'));
        }

        return $res;
    }

    public function write (string $p): int {
        return socket_write($this->socket, $p);
    }

    public function localAddr (): Address {
        // TODO: Implement localAddr() method.
    }

    public function remoteAddr (): Address {
        // TODO: Implement remoteAddr() method.
    }
}