<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$db = new PDO(
    'pgsql:host=127.0.0.1;port=5432;dbname=proxydb',
    'proxyuser',
    'strongpass',
    [
        PDO::ATTR_PERSISTENT => true
    ]
);

$ip4List = [
    "194.31.72.40",
    "194.31.72.41",
    "194.31.72.42",
    "194.31.72.44",
    "194.31.72.43"
];

$ip4 = $ip4List[array_rand($ip4List)];
$configDir = "/usr/local/3proxy/instances";
$authFileList = "/usr/local/3proxy/auth_users.txt";
$proxyBin = "/usr/bin/3proxy"; // Убедись, что путь правильный
$subnetPrefix = "2a09:a503";
$minPort = 10000;
$maxPort = 64000;

$user = $_GET['user'] ?? '';
$pwd  = $_GET['pwd'] ?? '';
$pid  = $_GET['pid'] ?? '';

if (!$user || !$pwd || !$pid) {
    http_response_code(400);
    exit("Missing user/pwd/pid");
}

// === Авторизация ===
$authList = file($authFileList, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$valid = false;
foreach ($authList as $auth) {
    [$u, $p] = explode(":", trim($auth), 2);
    if ($u === $user && $p === $pwd) {
        $valid = true;
        break;
    }
}
if (!$valid) {
    http_response_code(403);
    exit("Forbidden: invalid credentials");
}

$pidSafe = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $pid);
if (strlen($pidSafe) < 3) {
    http_response_code(400);
    exit("Invalid pid");
}

// === Генераторы ===
function generateString($length = 10): string {
    return bin2hex(random_bytes($length / 2));
}

function isPortActive($port): bool {
    $output = shell_exec("ss -ltn | grep ':$port '");
    return is_string($output) && strpos($output, (string)$port) !== false;
}

// === Получаем или генерим IPv6 ===
$stmt = $db->prepare("SELECT ipv6 FROM profiles WHERE pid = ?");
$stmt->execute([$pid]);
$profile = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$profile) {
    $ipv6Parts = [];
    for ($i = 0; $i < 6; $i++) {
        $ipv6Parts[] = dechex(random_int(0, 0xFFFF));
    }
    $ipv6 = $subnetPrefix . ":" . implode(":", $ipv6Parts);

    $stmt = $db->prepare("INSERT INTO profiles (pid, ipv6) VALUES (?, ?)");
    $stmt->execute([$pid, $ipv6]);
} else {
    $ipv6 = $profile['ipv6'];
}

// === Проверка существующего прокси ===
$authPath = "$configDir/pid_{$pidSafe}.auth";

if (file_exists($authPath)) {
    $authContent = file_get_contents($authPath);
    $authContent = is_string($authContent) ? trim($authContent) : '';
    $parts = explode(":", $authContent);

    if (count($parts) >= 3) {
        [$genUser, $genPass, $port] = $parts;
        if (isPortActive($port)) {
            header("Content-Type: text/plain");
            echo "$ip4:$port:$genUser:$genPass";
            exit;
        }
    } else {
        unlink($authPath); // удалим повреждённый файл
    }
}

// === Генерация новых данных ===
$genUser = generateString(8);
$genPass = generateString(12);

do {
    $port = random_int($minPort, $maxPort);
} while (isPortActive($port));

file_put_contents($authPath, "$genUser:$genPass:$port");

// === Генерация конфига ===
$confFile = "$configDir/pid_{$pidSafe}_" . time() . ".cfg";
$conf = <<<EOL
timeouts 1 5 30 60 180 1800 15 60
nserver 127.0.0.1
maxconn 1000
users $genUser:CL:$genPass
auth strong
allow $genUser
deny * * * * HTTP GET,POST,HEAD
proxy -6 -s0 -osTCP_NODELAY -ocTCP_NODELAY -p$port -a -n -i0.0.0.0 -e$ipv6
EOL;

file_put_contents($confFile, $conf);

// === Запуск 3proxy ===
$startCmd = "$proxyBin $confFile > /dev/null 2>&1 & echo $!";
$pid3proxy = trim(shell_exec($startCmd));

// === Очистка через 10 минут, если 3proxy запущен ===
if (!empty($pid3proxy) && is_numeric($pid3proxy)) {
    $cleanupCmd = "(sleep 600 && kill $pid3proxy && rm -f \"$confFile\" \"$authPath\") > /dev/null 2>&1 &";
    shell_exec($cleanupCmd);
}

// === Ответ клиенту ===
header("Content-Type: text/plain");
echo "$ip4:$port:$genUser:$genPass";
