<?php

require_once "Auth.php";
require_once "SmtpClient.php";


class ProxyService
{

    /**
     * 连接数
     * @var SmtpClient[]
     */
    protected static $clients = [];


    protected function push(...$params){
        echo co::getCid()." => ";
        echo implode(' => ',$params);
        return $params;
    }

    /**
     * @author:dc
     * @time 2025/3/29 14:34
     */
    public function run()
    {
        //创建Server对象,监听 127.0.0.1:9501 端口。
        $server = new Swoole\Server(
            '0.0.0.0', 9527,
            SWOOLE_BASE,
            SWOOLE_SOCK_TCP//|SWOOLE_SSL
        );

        //监听连接进入事件。
        $server->on('Connect', function ($server, $fd) {
            $server->send($fd, "220 proxy client ok\r\n");
        });

        //监听数据接收事件。
        $server->on('Receive', function ($server, $fd, $reactor_id, $data) {
//            echo "in ".co::getCid()." ==> ".$data."\n";
            // 建立连接
            if (empty(self::$clients[$fd])) {

                try {
                    $auth = new Auth($data);
                }catch (Throwable $e){
                    $server->send($fd, $e->getMessage());
                    $server->close($fd,true);
                    return;
                }
                // 创建一个客户端
                self::$clients[$fd] = new SmtpClient($auth->host);
                // 连接客户端
                try {
                    self::$clients[$fd]->open($auth->out_ip, $auth->timeOut);
                }catch (Throwable $e){
                    $server->send($fd, '500 ' . $e->getMessage()."\r\n");
                    $server->close($fd,true);
                    return;
                }

                $line = self::$clients[$fd]->readLine();

                if($line) $server->send($fd,$line);

                // 发送成功消息
//                $server->send($fd, "200 OK The proxy server is successfully connected.\r\n");

            } // 正式请求转发
            else {
                // 没有连接成功
                if(empty(self::$clients[$fd])){
                    $server->send($fd, "500 No proxy server.\r\n");
                    $server->close($fd,true);
                    return;
                }

                try {
                    // 请求数据
                    self::$clients[$fd]->write($data);

                    $line = self::$clients[$fd]->readLine();

                }catch (Throwable $e){
                    echo date('Y-m-d H:i:s').' 协程读取异常 ' .$data." ::".$e->getMessage()."\n";
                }

//                echo 'out '.co::getCid()." => ".$line;

                if($line!==false) $server->send($fd,$line);

            }
        });

        //监听连接关闭事件。
        $server->on('Close', function ($server, $fd) {
//            echo '连接关闭了 => '.$fd."\n";
            // 关闭并释放资源
            self::$clients[$fd] = null;
            unset(self::$clients[$fd]);
        });

        //启动服务器
        $server->start();
    }

}


(new ProxyService())->run();