#!/usr/bin/env python3
import argparse
import json
import os
import sys
import urllib.request
import urllib.error

# Default API Gateway URL (localhost forwarding from node06)
DEFAULT_API_URL = "http://localhost:8080"

def get_url(path):
    return f"{DEFAULT_API_URL}{path}"

def headers(token=None):
    h = {"Content-Type": "application/json"}
    if token:
        h["Authorization"] = f"Bearer {token}"
    return h

def print_json(data):
    print(json.dumps(data, indent=2))

def request(method, url, data=None, token=None):
    parsed_headers = headers(token)
    body = None
    if data:
        body = json.dumps(data).encode('utf-8')
    
    req = urllib.request.Request(url, data=body, headers=parsed_headers, method=method)
    
    try:
        with urllib.request.urlopen(req) as response:
            if response.status in [200, 201, 204]:
                if response.status == 204:
                    print("{}")
                    return
                resp_data = json.load(response)
                print_json(resp_data)
            else:
                print(f"Error {response.status}")
    except urllib.error.HTTPError as e:
        print(f"HTTP Error {e.code}: {e.read().decode()}")
    except urllib.error.URLError as e:
        print(f"Connection failed: {e.reason}")

def cmd_list_vpcs(args):
    url = get_url("/api/v1/vpcs")
    print(f"GET {url}")
    request("GET", url, token=args.token)

def cmd_create_vpc(args):
    url = get_url("/api/v1/vpcs")
    data = {
        "name": args.name,
        "cidr_block": args.cidr,
        "org_id": "org-default",
        "project_id": "proj-default"
    }
    print(f"POST {url} with {data}")
    request("POST", url, data=data, token=args.token)

def cmd_list_subnets(args):
    url = get_url("/api/v1/subnets")
    if args.vpc:
        url += f"?vpc_id={args.vpc}"
    print(f"GET {url}")
    request("GET", url, token=args.token)

def cmd_create_subnet(args):
    url = get_url("/api/v1/subnets")
    data = {
        "name": args.name,
        "vpc_id": args.vpc,
        "cidr_block": args.cidr,
        "org_id": "org-default",
        "project_id": "proj-default"
    }
    print(f"POST {url} with {data}")
    request("POST", url, data=data, token=args.token)

def cmd_list_vms(args):
    url = get_url("/api/v1/vms")
    print(f"GET {url}")
    request("GET", url, token=args.token)

def main():
    global DEFAULT_API_URL
    parser = argparse.ArgumentParser(description="UltraCloud CLI")
    parser.add_argument("--token", help="Auth token", default=os.environ.get("CLOUD_TOKEN"))
    parser.add_argument("--url", help="API URL", default=DEFAULT_API_URL)

    subparsers = parser.add_subparsers(dest="command", required=True)
    
    # VPC Commands
    vpc_parser = subparsers.add_parser("vpc", help="Manage VPCs")
    vpc_sub = vpc_parser.add_subparsers(dest="subcommand", required=True)
    
    vpc_list = vpc_sub.add_parser("list", help="List VPCs")
    vpc_list.set_defaults(func=cmd_list_vpcs)
    
    vpc_create = vpc_sub.add_parser("create", help="Create VPC")
    vpc_create.add_argument("--name", required=True)
    vpc_create.add_argument("--cidr", required=True)
    vpc_create.set_defaults(func=cmd_create_vpc)

    # Subnet Commands
    subnet_parser = subparsers.add_parser("subnet", help="Manage Subnets")
    subnet_sub = subnet_parser.add_subparsers(dest="subcommand", required=True)

    subnet_list = subnet_sub.add_parser("list", help="List Subnets")
    subnet_list.add_argument("--vpc", help="Filter by VPC ID")
    subnet_list.set_defaults(func=cmd_list_subnets)

    subnet_create = subnet_sub.add_parser("create", help="Create Subnet")
    subnet_create.add_argument("--name", required=True)
    subnet_create.add_argument("--vpc", required=True, help="VPC ID")
    subnet_create.add_argument("--cidr", required=True)
    subnet_create.set_defaults(func=cmd_create_subnet)

    # VM Commands
    vm_parser = subparsers.add_parser("vm", help="Manage VMs")
    vm_sub = vm_parser.add_subparsers(dest="subcommand", required=True)
    
    vm_list = vm_sub.add_parser("list", help="List VMs")
    vm_list.set_defaults(func=cmd_list_vms)

    args = parser.parse_args()
    if args.url:
        DEFAULT_API_URL = args.url
        
    args.func(args)

if __name__ == "__main__":
    main()
