<?php

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response as WebmanResponse;
use yzh52521\EasyHttp\Http;
use yzh52521\EasyHttp\Response;
use yzh52521\EasyHttp\RequestException;


require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('tcp://0.0.0.0:8686');

function encryptAES($data, $key, $iv) {    
    $encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);  
    $encrypted = base64_encode($encrypted);  
    return $encrypted;  
}  
  
function decryptAES($encryptedData, $key, $iv) {  
    $encryptedData = base64_decode($encryptedData);  
    $decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);  
    return $decrypted;  
}  
function replaceHost($data,$host)
{
    return preg_replace('/Host: (.*)/i','Host: '.$host,$data);
}
function HTMLview($filePath, $data) {
    ob_start();
    extract($data);
    include $filePath;
    $str = ob_get_contents();
    ob_end_clean();
 
    return $str;
}
$worker->onConnect = function(TcpConnection $connection, Request $data)
{
    $config=json_decode(file_get_contents("./config.json"));

    $matched=false;
    foreach($config->website as $website){
        if($website->query==$data->host(true)){
            $config->website=$website;
            $c_provider=$website->provider;
            $config->provider=$config->provider->$c_provider;
            $matched=true;
            break;
        }
    }
    if($matched==false){
        $connection->send(HTMLview('./view/404.php', array()));
      $connection->close();
    }else{

    $tWT = $data->cookie('WT', 'null');
    if($tWT!='null'){
        $key = 'laysensechina000';
        $iv = '1234567890abcdef';
        $wt=json_decode(decryptAES($tWT, $key, $iv));
        if(time()-$wt->time<60){
            $tWT=='null';
        }
    }
    if($tWT=='null'){
        if(strpos( $data->path(), "/login" ) === 0){
            if( $data->path()=='/login/qywx/' ){
                $code = $data->get('code','null');
                if($code=='null'){
                    $connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
                    $connection->close();

                }else{
                    $http = new Workerman\Http\Client();
                    $tokenfile='./'.$config->website->api->qywx->appid.'.'.$config->website->api->qywx->agentid.'.token';
                    echo $tokenfile;
                    if(file_exists($tokenfile)){
                        $tokencontent=json_decode(file_get_contents($tokenfile));
                        $fulltoken=$tokencontent->token;
                        $ddl=$tokencontent->ddl;
                        if($ddl-time()<180){
                            $reapply=true;
                        }else{
                            $reapply=false;
                        }
                    }else{
                        $reapply=true;
                    }

                    if($reapply==true){
                        $apply=$response = Http::get('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.$config->website->api->qywx->appid.'&corpsecret='.$config->website->api->qywx->token)->json();
                        $fulltoken=$apply->access_token;
                            $ddl=time()+$apply->expires_in;
                            $file=fopen($tokenfile,"w");
                            fwrite($file, json_encode(array('token'=>$fulltoken,'ddl'=>$ddl)));
                            fclose($file);
                    }
                    $lookup= Http::get('https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token='.$fulltoken.'&code='.$code)->json();
                    if($lookup->errcode!=0){
                        $connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
                        $connection->close();
                    }else{
                    $userid=$lookup->userid;
                    $userinfo=Http::get('https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token='.$fulltoken.'&userid='.$userid)->json();
                    $username=$userinfo->name;
                    $userposition=$userinfo->position;
                    $WT=json_encode(['id'=>$userid,'name'=>$username,'position'=>$userposition,'time'=>time()]);
                    $key = 'laysensechina000';
                    $iv = '1234567890abcdef';
                    $WT = encryptAES($WT, $key, $iv);  
                    $dest=$data->get('jump','/');
                    $response = new WebmanResponse(200, [], HTMLview('./view/jump.php', array('website'=>$config->website,'provider'=>$config->provider,'userinfo'=>$userinfo,'dest'=>$dest)));
                    $response->cookie('WT', $WT,time()+9600,'/','.laysense.cn');
                    
                    $connection->send($response);
                    $connection->close();
                    }
                }
            }
        }else{
            $connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>null,'uri'=>$data->uri())));
            $connection->close();
        }
    }else{


     // Parse http header.
     list($method, $addr, $http_version) = explode(' ', $data);
     $_headers=explode("\r\n",$data);
     $headers=[];
     foreach ($_headers as $_header){
         $_point=strpos($_header,':');
         if ($_point===false) continue;
         $headers[substr($_header,0,$_point)]=trim(trim(substr($_header,$_point),':'));
     }

     //源站IP地址
     $source_ip=$config->website->ip;
     $port=$config->website->port;
     $source_host=$config->website->host;
     $ssl=$config->website->ssl;


     print_r('用户IP:'.$data->header('X-Real-IP','127.0.0.1').'| 访问路径:'.$data->host().$data->uri() .' | 源站:'.$source_ip.':'.$port.'| 回源域名'.$source_host.'|SSL:'.$ssl);
     if($ssl==true){
        $source_ip=$source_host;
     }
     // Async TCP connection.
     $remote_connection = new AsyncTcpConnection('tcp://'.$source_ip.':'.$port);
     // CONNECT.
     if($ssl==true){
        $remote_connection->transport = 'ssl';
     }

     if ($method !== 'CONNECT') {
         //替换request 中的回源host
         $remote_connection->send(replaceHost($data,$source_host));
         // POST GET PUT DELETE etc.
     } else {
         $connection->send("HTTP/1.1 200 Connection Established\r\n\r\n");
     }
    
     $remote_connection->onMessage=function (TcpConnection $SourceConn, $SourceData)use ($connection){
         $connection->send($SourceData);
     };

     $remote_connection->onClose = function ($source) use ($connection) {
         $connection->close();
     };

     $remote_connection->onBufferFull = function ($SourceConn) use ($connection) {
         $connection->pauseRecv();
     };

     $remote_connection->onBufferDrain = function ($SourceConn) use ($connection) {
         $connection->resumeRecv();
     };

     $connection->onMessage=function (TcpConnection $ClientConn, $ClientData)use ($remote_connection,$source_host){
         $remote_connection->send(replaceHost($ClientData,$source_host));
     };

     $connection->onClose = function (TcpConnection $ClientConn) use ($remote_connection) {
         $remote_connection->close();
     };

     $connection->onBufferFull = function (TcpConnection $ClientConn) use ($remote_connection) {
         $remote_connection->pauseRecv();
     };

     $connection->onBufferDrain = function (TcpConnection $ClientConn) use ($remote_connection) {
         $remote_connection->resumeRecv();
     };

     $remote_connection->connect();
    }
}
};

// 运行worker
Worker::runAll();