#!/usr/bin/env python3
"""Simple ZeroTier helper for joining networks and discovering peers.

Usage:
  python scripts/zerotier_setup.py --join <network_id>
  python scripts/zerotier_setup.py --list
  python scripts/zerotier_setup.py --discover <network_id>

This is a convenience tool to exercise the API/zerotier.py functionality while
prototyping and bringing up remote peers for store testing.
"""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from SYS.logger import log

try:
    from API import zerotier
except Exception:
    zerotier = None


def main(argv=None):
    parser = argparse.ArgumentParser(description="ZeroTier helper for Medios-Macina")
    parser.add_argument("--list", action="store_true", help="List local ZeroTier networks")
    parser.add_argument("--join", type=str, help="Join a ZeroTier network by ID")
    parser.add_argument("--leave", type=str, help="Leave a ZeroTier network by ID")
    parser.add_argument("--discover", type=str, help="Discover services on a ZeroTier network ID")
    parser.add_argument("--upload", type=str, help="Upload a file to a discovered 'remote' service on this ZeroTier network ID")
    parser.add_argument("--file", type=str, help="Local file to upload (used with --upload)")
    parser.add_argument("--tag", action="append", help="Tag to attach (repeatable)", default=[])
    parser.add_argument("--url", action="append", help="URL to associate (repeatable)", default=[])
    parser.add_argument("--api-key", type=str, help="API key to use for uploads (optional)")
    parser.add_argument("--json", action="store_true", help="Output JSON when appropriate")
    args = parser.parse_args(argv)

    if zerotier is None:
        log("ZeroTier API module not available; ensure API/zerotier.py is importable and zerotier or zerotier-cli is installed")
        return 1

    if args.list:
        nets = zerotier.list_networks()
        if args.json:
            print(json.dumps([n.__dict__ for n in nets], indent=2))
        else:
            for n in nets:
                print(f"{n.id}\t{name:=}{n.name}\t{n.status}\t{n.assigned_addresses}")
        return 0

    if args.join:
        try:
            ok = zerotier.join_network(args.join)
            print("Joined" if ok else "Failed to join")
            return 0 if ok else 2
        except Exception as exc:
            log(f"Join failed: {exc}")
            print(f"Join failed: {exc}")
            return 2

    if args.leave:
        try:
            ok = zerotier.leave_network(args.leave)
            print("Left" if ok else "Failed to leave")
            return 0 if ok else 2
        except Exception as exc:
            log(f"Leave failed: {exc}")
            print(f"Leave failed: {exc}")
            return 2

    if args.discover:
        probes = zerotier.discover_services_on_network(args.discover)
        if args.json:
            print(json.dumps([p.__dict__ for p in probes], indent=2, default=str))
        else:
            for p in probes:
                print(f"{p.address}:{p.port}{p.path} -> status={p.status_code} hint={p.service_hint}")
        return 0

    if args.upload:
        # Upload a file to the first discovered remote service on the network
        if not args.file:
            print("ERROR: --file is required for --upload")
            return 2

        probe = zerotier.find_peer_service(args.upload, service_hint="remote")
        if not probe:
            print("No remote service found on network")
            return 2

        base = f"http://{probe.address}:{probe.port}"
        try:
            import httpx
            url = base.rstrip("/") + "/files/upload"
            headers = {}
            if args.api_key:
                headers["X-API-Key"] = args.api_key
            with open(args.file, "rb") as fh:
                files = {"file": (Path(args.file).name, fh)}
                data = []
                for t in (args.tag or []):
                    data.append(("tag", t))
                for u in (args.url or []):
                    data.append(("url", u))
                resp = httpx.post(url, files=files, data=data, headers=headers, timeout=30)
                print(resp.status_code, resp.text)
                return 0 if resp.status_code in (200, 201) else 2
        except Exception:
            import requests
            url = base.rstrip("/") + "/files/upload"
            headers = {}
            if args.api_key:
                headers["X-API-Key"] = args.api_key
            with open(args.file, "rb") as fh:
                files = {"file": (Path(args.file).name, fh)}
                data = []
                for t in (args.tag or []):
                    data.append(("tag", t))
                for u in (args.url or []):
                    data.append(("url", u))
                resp = requests.post(url, files=files, data=data, headers=headers, timeout=30)
                print(resp.status_code, resp.text)
                return 0 if resp.status_code in (200, 201) else 2

    parser.print_help()
    return 0


if __name__ == "__main__":
    sys.exit(main())