#!/usr/bin/env python3
import subprocess, http.server, json, random

TOR_PROXY = "172.21.0.2:59040"
DNS = "8.8.8.8"
IFACE = "ADMINS"
EXIT = ["DE"]
COUNTRIES = ["DE","US","JP","FR","NL","CH","GB","SE","NO","FI","ZA"]

def run(c): subprocess.run(c, shell=True, capture_output=True)

def is_tor():
    r = subprocess.run("docker exec wiregate ps aux | grep -v grep | grep tor", shell=True, capture_output=True, text=True)
    return "tor" in r.stdout

def get_country():
    r = subprocess.run("curl -s https://api.country.is", shell=True, capture_output=True, text=True)
    try:
        return json.loads(r.stdout).get("country", "")
    except:
        return ""

def start_tor(country):
    EXIT[0] = country
    run(f"docker exec wiregate bash -c \"sed -i 's/ExitNodes {{.*}}/ExitNodes {{{country}}}/' /etc/tor/torrc\"")
    run("docker exec wiregate pkill tor 2>/dev/null || true")
    run('docker exec -d wiregate bash -c "mkdir -p /WireGate/log /var/log/tor && tor"')

def enable(country="DE"):
    run("docker exec wiregate iptables -t nat -F PREROUTING")
    run(f"docker exec wiregate iptables -t nat -A PREROUTING -i {IFACE} -p udp --dport 53 -j DNAT --to-destination {DNS}:53")
    run(f"docker exec wiregate iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE")
    for net in ["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]:
        run(f"docker exec wiregate iptables -t nat -A PREROUTING -i {IFACE} -d {net} -j RETURN")
    run(f"docker exec wiregate iptables -t nat -A PREROUTING -i {IFACE} -p tcp -j DNAT --to-destination {TOR_PROXY}")
    start_tor(country)

def disable():
    run("docker exec wiregate iptables -t nat -F PREROUTING")
    run(f"docker exec wiregate iptables -t nat -A PREROUTING -i {IFACE} -p udp --dport 53 -j DNAT --to-destination {DNS}:53")
    run(f"docker exec wiregate iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE")
    run("docker exec wiregate pkill tor 2>/dev/null || true")

HTML = open("/opt/homelab/wiregate/tor.html").read()

class H(http.server.BaseHTTPRequestHandler):
    def log_message(self, f, *a): pass
    def do_GET(self):
        if self.path == "/":
            self.send_response(200)
            self.send_header("Content-type", "text/html;charset=utf-8")
            self.end_headers()
            self.wfile.write(open("/opt/homelab/wiregate/tor.html").read().encode("utf-8"))
        elif self.path == "/status":
            active = is_tor()
            country = get_country() if active else ""
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.end_headers()
            self.wfile.write(json.dumps({"tor": active, "country": country, "exit": EXIT[0]}).encode())
    def do_POST(self):
        n = int(self.headers.get("Content-Length", 0))
        d = json.loads(self.rfile.read(n)) if n else {}
        if self.path == "/toggle":
            enable(d.get("country", "DE")) if d.get("tor") else disable()
        elif self.path == "/setcountry":
            start_tor(d.get("country", "DE"))
        elif self.path == "/newcircuit":
            c = random.choice([x for x in COUNTRIES if x != EXIT[0]])
            start_tor(c)
        self.send_response(200)
        self.end_headers()

http.server.HTTPServer(("0.0.0.0", 8888), H).serve_forever()
