#!/usr/bin/env python3
"""Parse VLESS subscription links and generate mihomo config."""

import base64
import json
import urllib.parse
import yaml
import sys
import subprocess

def parse_vless_link(link):
    """Parse a single VLESS link into a proxy dict."""
    # Remove vless:// prefix
    link = link.strip()
    if not link.startswith('vless://'):
        return None

    link = link[8:]

    # Split by # to get name
    parts = link.split('#')
    name = urllib.parse.unquote(parts[1]) if len(parts) > 1 else 'unknown'

    # Split by @ to get uuid and server
    uuid_server = parts[0].split('@', 1)
    uuid = uuid_server[0]
    server_params = uuid_server[1].split('?', 1)

    server_port = server_params[0].split(':')
    server = server_port[0]
    port = int(server_port[1]) if len(server_port) > 1 else 443

    # Parse query params
    params = {}
    if len(server_params) > 1:
        params = urllib.parse.parse_qs(server_params[1])

    # Extract params
    security = params.get('security', ['tls'])[0]
    sni = params.get('sni', [''])[0]
    flow = params.get('flow', [''])[0]
    network = params.get('type', ['ws'])[0]
    fp = params.get('fp', ['chrome'])[0]

    proxy = {
        'name': name,
        'type': 'vless',
        'server': server,
        'port': port,
        'uuid': uuid,
        'udp': True,
        'tls': security == 'tls' or security == 'reality',
        'network': network,
        'client-fingerprint': fp,
    }

    if sni:
        proxy['servername'] = sni

    if flow and flow != 'none':
        proxy['flow'] = flow

    if security == 'reality':
        proxy['reality-opts'] = {
            'public-key': params.get('pbk', [''])[0],
            'short-id': params.get('sid', [''])[0],
        }

    if network == 'ws':
        ws_opts = {}
        path = params.get('path', [''])[0]
        host = params.get('host', [''])[0]
        if path:
            ws_opts['path'] = path
        if host:
            ws_opts['headers'] = {'Host': host}
        proxy['ws-opts'] = ws_opts

    return proxy


def main():
    # Fetch subscription
    result = subprocess.run(
        ['curl', '-sL', sys.argv[1]],
        capture_output=True, text=True
    )

    # Decode base64
    decoded = base64.b64decode(result.stdout.strip()).decode('utf-8')
    links = [l.strip() for l in decoded.split('\n') if l.strip().startswith('vless://')]

    # Parse all links
    proxies = []
    for link in links:
        proxy = parse_vless_link(link)
        if proxy:
            proxies.append(proxy)

    # Print summary
    print(f"Found {len(proxies)} nodes:")
    for p in proxies:
        print(f"  - {p['name']} ({p['server']}:{p['port']})")

    # Generate mihomo config
    proxy_names = [p['name'] for p in proxies]

    config = {
        'mixed-port': 7890,
        'socks-port': 7891,
        'port': 7892,
        'allow-lan': False,
        'mode': 'rule',
        'log-level': 'info',
        'external-controller': '127.0.0.1:9090',
        'dns': {
            'enable': True,
            'listen': '0.0.0.0:53',
            'enhanced-mode': 'fake-ip',
            'fake-ip-range': '198.18.0.1/16',
            'nameserver': ['223.5.5.5', '119.29.29.29'],
            'fallback': ['8.8.8.8', '1.1.1.1'],
        },
        'proxies': proxies,
        'proxy-groups': [
            {
                'name': 'Proxy',
                'type': 'select',
                'proxies': ['AUTO', 'DIRECT'] + proxy_names,
            },
            {
                'name': 'AUTO',
                'type': 'url-test',
                'proxies': proxy_names,
                'url': 'https://www.gstatic.com/generate_204',
                'interval': 300,
            },
            {
                'name': 'Streaming',
                'type': 'select',
                'proxies': proxy_names,
            },
        ],
        'rules': [
            'DOMAIN-SUFFIX,google.com,Proxy',
            'DOMAIN-SUFFIX,github.com,Proxy',
            'DOMAIN-SUFFIX,github.io,Proxy',
            'DOMAIN-SUFFIX,githubusercontent.com,Proxy',
            'DOMAIN-SUFFIX,youtube.com,Streaming',
            'DOMAIN-SUFFIX,ytimg.com,Streaming',
            'DOMAIN-SUFFIX,netflix.com,Streaming',
            'DOMAIN-SUFFIX,nflxvideo.net,Streaming',
            'DOMAIN-SUFFIX,twitter.com,Proxy',
            'DOMAIN-SUFFIX,x.com,Proxy',
            'DOMAIN-SUFFIX,telegram.org,Proxy',
            'DOMAIN-SUFFIX,t.me,Proxy',
            'DOMAIN-SUFFIX,googleapis.com,Proxy',
            'DOMAIN-SUFFIX,googleusercontent.com,Proxy',
            'DOMAIN-SUFFIX,gstatic.com,Proxy',
            'DOMAIN-SUFFIX,openai.com,Proxy',
            'DOMAIN-SUFFIX,anthropic.com,Proxy',
            'DOMAIN-SUFFIX,claude.ai,Proxy',
            'GEOIP,CN,DIRECT',
            'MATCH,Proxy',
        ],
    }

    with open('/home/longshao/.config/mihomo/config.yaml', 'w') as f:
        yaml.dump(config, f, allow_unicode=True, default_flow_style=False, sort_keys=False)

    print(f"\nConfig written to ~/.config/mihomo/config.yaml")
    print(f"Total: {len(proxies)} proxies")


if __name__ == '__main__':
    main()
