import os
import requests
import json
import argparse
import sys
from typing import Optional, Dict, List

class CloudflareManager:
    """
    Genesis Cloudflare Manager
    Automates Zone creation and DNS record setup for GHL.
    """
    
    API_BASE = "https://api.cloudflare.com/client/v4"
    
    def __init__(self, api_token: Optional[str] = None):
        self.api_token = api_token or os.environ.get("CLOUDFLARE_API_TOKEN")
        if not self.api_token:
            print("[!] Error: CLOUDFLARE_API_TOKEN not found in environment.")
            sys.exit(1)
            
        self.headers = {
            "Authorization": f"Bearer {self.api_token}",
            "Content-Type": "application/json"
        }

    def _get(self, endpoint: str) -> Dict:
        response = requests.get(f"{self.API_BASE}/{endpoint}", headers=self.headers)
        return response.json()

    def _post(self, endpoint: str, data: Dict) -> Dict:
        response = requests.post(f"{self.API_BASE}/{endpoint}", headers=self.headers, json=data)
        return response.json()

    def get_zone_id(self, domain_name: str) -> Optional[str]:
        """Find the Zone ID for a domain."""
        res = self._get(f"zones?name={domain_name}")
        if res.get("success") and res["result"]:
            return res["result"][0]["id"]
        return None

    def add_zone(self, domain_name: str) -> Dict:
        """Add a new domain (zone) to Cloudflare."""
        print(f"[*] Adding zone: {domain_name}...")
        data = {"name": domain_name, "jump_start": True}
        return self._post("zones", data)

    def get_nameservers(self, zone_id: str) -> List[str]:
        """Retrieve nameservers assigned to the zone."""
        res = self._get(f"zones/{zone_id}")
        if res.get("success"):
            return res["result"].get("name_servers", [])
        return []

    def set_ghl_records(self, zone_id: str):
        """Configure A and CNAME records for GHL."""
        print(f"[*] Configuring GHL DNS records for Zone {zone_id}...")
        
        # 1. A Record @ -> 34.102.32.115
        a_record = {
            "type": "A",
            "name": "@",
            "content": "34.102.32.115",
            "proxied": False,
            "ttl": 3600
        }
        res_a = self._post(f"zones/{zone_id}/dns_records", a_record)
        if res_a.get("success"):
            print("  ✓ A Record set: @ -> 34.102.32.115")
        else:
            print(f"  [!] Failed to set A Record: {res_a.get('errors')}")

        # 2. CNAME www -> flash.funnels.msgsndr.com
        cname_record = {
            "type": "CNAME",
            "name": "www",
            "content": "flash.funnels.msgsndr.com",
            "proxied": False,
            "ttl": 3600
        }
        res_cname = self._post(f"zones/{zone_id}/dns_records", cname_record)
        if res_cname.get("success"):
            print("  ✓ CNAME set: www -> flash.funnels.msgsndr.com")
        else:
            print(f"  [!] Failed to set CNAME: {res_cname.get('errors')}")

def main():
    parser = argparse.ArgumentParser(description="Genesis Cloudflare DNS Manager")
    parser.add_argument("--domain", required=True, help="Domain name to manage")
    parser.add_argument("--add-zone", action="store_true", help="Add the domain to Cloudflare")
    parser.add_argument("--setup-ghl", action="store_true", help="Configure GHL records")
    parser.add_argument("--token", help="Cloudflare API Token")

    args = parser.parse_args()
    
    cf = CloudflareManager(api_token=args.token)
    
    zone_id = cf.get_zone_id(args.domain)
    
    if args.add_zone:
        if zone_id:
            print(f"[!] Zone for {args.domain} already exists (ID: {zone_id})")
        else:
            res = cf.add_zone(args.domain)
            if res.get("success"):
                zone_id = res["result"]["id"]
                ns = cf.get_nameservers(zone_id)
                print(f"[OK] Zone created. Nameservers: {', '.join(ns)}")
            else:
                print(f"[!] Failed to add zone: {res.get('errors')}")
                sys.exit(1)
                
    if args.setup_ghl:
        if not zone_id:
            print(f"[!] Target zone for {args.domain} not found. Use --add-zone first.")
            sys.exit(1)
        cf.set_ghl_records(zone_id)

if __name__ == "__main__":
    main()
