<?php
namespace app\controller;

use support\Request;
use support\Log;
use Symfony\Component\Process\Process;
use support\Response;

class GitController
{
    private string $secret = 'a66fb7936210d94960ac9b4e0c8bd3ef45f8f3e1';

    public function test(Request $request): Response
    {
        $this->dispatchUpdate('bang_server.sh');
        return response('Test webhook executed');
    }
    public function handle(Request $request): Response
    {
        // 1. IP白名单验证（仅接受GitHub请求）
        $allowedIps = ['110.42.52.196'];
        if($request->method() !== 'POST'){
            return response('Method Not Allowed', 405);
        }
        
        $clientIp = $request->header('x-real-ip', $request->getRealIp());
        $isValidIp = false;
        
        foreach ($allowedIps as $range) {
            if ($this->ipInRange($clientIp, $range)) {
                $isValidIp = true;
                break;
            }
        }
        
        if (!$isValidIp) {
            Log::warning("Unauthorized IP: {$clientIp}");
            return response('IP not allowed', 403);
        }

        // 2. 签名验证
        $signature = $request->header('x-hub-signature-256');
        $payload = $request->rawBody();
        $json = json_decode($payload, true);
        $script_fn = "";
        if($json['repository']['full_name'] == 'commie/wenjuanbang_server')
        {
            if($json['ref'] == 'refs/heads/main'){
                $script_fn = 'bang_server.sh';
            }
            if($json['ref'] == 'refs/heads/xi'){
                $script_fn = 'xi_server.sh';
            }
        }else  if($json['repository']['full_name'] == 'commie/cdkey'){
            if($json['ref'] == 'refs/heads/xi'){
                $script_fn = 'wjx_cdkey.sh';
            }
            if($json['ref'] == 'refs/heads/wjb'){
                $script_fn = 'wjb_cdkey.sh';
            }
        }
        //log_alert($script_fn);
        if(!$script_fn){
            return response('Not main branch', 200);
        }

        if (!$this->verifySignature($payload, $signature)) {
            Log::warning("Invalid signature from {$clientIp}");
            return response('Invalid signature', 403);
        }

        // 3. 异步更新
        $this->dispatchUpdate($script_fn);
        return response('Webhook received successfully');
    }

    private function ipInRange(string $ip, string $range): bool
    {
        [$subnet, $bits] = explode('/', $range);
        $ip = ip2long($ip);
        $subnet = ip2long($subnet);
        $mask = -1 << (32 - $bits);
        return ($ip & $mask) === ($subnet & $mask);
    }

    private function verifySignature(string $payload, ?string $signature): bool
    {
        $computedSignature = 'sha256=' . hash_hmac('sha256', $payload, $this->secret);
        return hash_equals($computedSignature, $signature ?? '');
    }

    private function dispatchUpdate($script_fn): void
    {
        $scriptPath = base_path('scripts/'.$script_fn);
        $outputFile = runtime_path('logs').'/'.$script_fn.'.log';
        // 使用su命令切换到您的用户
        $command = "bash {$scriptPath} > {$outputFile} 2>&1";
        
        // 后台执行
        shell_exec("nohup {$command} &");
    }
}