<?php
// namespace TestSuite;

require_once(dirname(__FILE__) . '/Error/SocketError.php');
// use \TestSuite\Exceptions\SocketError;

/**
 * Socket连接类
 */
class Connection
{
	const READ_SIZE = 1024;

	protected $socket = null;
	protected $options;

	/**
	 * 创建一个新的socket连接.
	 * Options may be:
	 * - host (default: 127.0.0.1)
	 * - port (default: 3000)
	 *
	 * @param socket配置信息
	 */
	public function __construct($options)
	{
		$defaults = [
			'host' 	=> '127.0.0.1',
			'port'	=> '3000'
		];

		$this->options 	= $options + $defaults;
		$this->socket 	= socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	}

	/**
	 * 建立socket连接
	 *
	 * @return bool
	 * @throws Exceptions\SocketError
	 */
	public function connect()
	{
		if (@socket_connect($this->socket, $this->options['host'], $this->options['port'])) {
			socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, [
				'sec'	=> 50,
				'usec'	=> 0
			]);

			return true;
		}

		throw new SocketError('Socket连接错误: ' . socket_last_error($this->socket));
	}

	/**
	 * 关闭socket
	 *
	 * @return void
	 */
	public function disconnect()
	{
		socket_shutdown($this->socket, 2);
		socket_close($this->socket);
		$this->socket = null;
	}

	/**
	 * 发送socket数据，并读取返回信息.
	 *
	 * @param  string $data Hexed data string
	 *
	 * @throws TypeError
	 * @return string       Answer returned from socket
	 */
	public function write($data)
	{
		// if (!ctype_xdigit($data)) {
		// 	throw new TypeError('$data必须是16进制字符串');
		// }

		if ($this->socket === null) {
			$this->connect();
		}

		// $binaryData = '';

		// if ( !function_exists( 'hex2bin' ) ) {

		// 	print_r('expression1');
			// $len = strlen( $data );
			// for ( $i = 0; $i < $len; $i += 2 ) {
			// 	$binaryData .= pack( "H2", substr( $data, $i, 2 ) );
			// }
		// }else{
		// 	print_r('expression2');
			$binaryData = hex2bin($data);
		// }
		// $binaryData = $data;
// print_r("<pre>发送报文 => $data</pre>");
		//发送数据
		socket_write($this->socket, $binaryData);

// print_r('<pre>应答数据 => ');
		//读取应答数据
		$s      = $this->socket;
		$buffer = socket_read($s, self::READ_SIZE);

		if (!$buffer) {
			throw new SocketError('应答数据为空！');
		}

		$sockets = [$s];
		while(socket_select($sockets, $w, $e, 0)) {
			$buffer .= socket_read($s, self::READ_SIZE);
			$sockets = [$s];
		}

		$buffer = bin2hex($buffer);
// print_r('$buffer');

// print_r('<pre>应答数据 => ');
// 		$buffer = '';
// 		if (false !== ($bytes = socket_recv($socket, $buffer, 2048, MSG_WAITALL))) {
// print_r ("共读取$bytes字节数据：");
// 		    if (!$buffer) {
// 				throw new SocketError('应答数据为空！');
// 		    }
// 		} else {
// 		    throw new SocketError ("应答数据读取失败，原因: " . socket_strerror(socket_last_error($socket)));
// 		}

// print_r('</pre>');
		socket_close($this->socket);

		return $buffer;
	}
}
