# -*- coding:utf8 -*-
import json
import subprocess
import time
import os
import re


def parse_vless (url):
	try:
		memo = url.split ('#') [1] if '#' in url else "未知节点"
		match = re.match (r"vless://([^@]+)@([^:]+):(\d+)\?(.*)",url.split ('#') [0])
		if not match: return None
		uuid,addr,port,query = match.groups ()
		params = dict (item.split ('=') for item in query.split ('&'))
		return {
			"uuid": uuid,"addr": addr,"port": int (port),
			"pbk": params.get ('pbk'),"sid": params.get ('sid'),
			"sni": params.get ('sni','www.microsoft.com'),
			"memo": memo
		}
	except:
		return None


def check_vless ():
	# --- 核心路径逻辑：指定你的子文件夹 ---
	XRAY_FOLDER = "Xray-macos-arm64-v8a"
	XRAY_BIN = os.path.join (XRAY_FOLDER,"xray")

	print ("\n" + "=" * 55)
	print ("🚀 Mac ARM 版 VLESS 拨测工具 (子文件夹内核模式)")
	print (f"📂 内核路径: {XRAY_BIN}")
	print ("=" * 55)

	# 检查内核是否存在
	if not os.path.exists (XRAY_BIN):
		print (f"❌ 错误：在 {XRAY_BIN} 未找到 xray 文件！")
		print (f"请检查文件夹名称是否准确，或执行: chmod +x {XRAY_BIN}")
		return

	while True:
		url = input ("\n[请输入 VLESS 链接] (输入 'q' 退出):\n> ").strip ()
		if url.lower () == 'q': break
		data = parse_vless (url)
		if not data:
			print ("❌ 链接格式错误！")
			continue

		config_path = "v_check_temp.json"
		tmp_port = 29999

		config = {
			"inbounds": [{"port": tmp_port,"protocol": "socks","settings": {"udp": True}}],
			"outbounds": [{
				"protocol": "vless",
				"settings": {"vnext": [{"address": data ['addr'],"port": data ['port'],"users": [
					{"id": data ['uuid'],"encryption": "none","flow": "xtls-rprx-vision"}]}]},
				"streamSettings": {
					"network": "tcp","security": "reality",
					"realitySettings": {"show": False,"fingerprint": "chrome","serverName": data ['sni'],
					                    "publicKey": data ['pbk'],"shortId": data ['sid']}
				}
			}]
		}

		with open (config_path,'w') as f:
			json.dump (config,f)

		print (f"📡 正在启动内核拨测: {data ['memo']}...")

		# 核心修改：使用绝对路径或相对路径调用子文件夹内的 xray
		# 加上 chmod 确保权限（以防万一）
		os.chmod (XRAY_BIN,0o755)

		proc = subprocess.Popen (
			[f"./{XRAY_BIN}","-config",config_path],
			stdout = subprocess.DEVNULL,
			stderr = subprocess.PIPE,
			text = True
		)

		# 给 Reality 握手留足时间 (跨境测试建议 3 秒)
		time.sleep (3)

		# 检查进程状态
		if proc.poll () is not None:
			err = proc.stderr.read ()
			print (f"❌ 内核启动失败！原因: {err}")
			continue

		# 拨测逻辑 (测百度)
		start_t = time.time ()
		# Mac 的 curl 配合 socks5h 代理
		test_cmd = f"curl -x socks5h://127.0.0.1:{tmp_port} -o /dev/null -s -w '%{{http_code}}' --connect-timeout 10 https://www.baidu.com"

		res_code = subprocess.getoutput (test_cmd).strip ()

		if res_code == "200":
			latency = int ((time.time () - start_t) * 1000)
			print (f"✅ 【连接成功】 实时延迟: {latency}ms")
		else:
			print (f"❌ 【连接失败】 状态码: {res_code}")
			print ("💡 提示：如果状态码是 000，请检查 Mac 是否弹出了‘安全拦截’提示。")

		# 彻底清理
		proc.terminate ()
		subprocess.run ("pkill -f xray",shell = True,stdout = subprocess.DEVNULL,stderr = subprocess.DEVNULL)
		if os.path.exists (config_path): os.remove (config_path)


if __name__ == "__main__":
	check_vless ()















