#!/usr/bin/env python3
"""
Automate Cloudflare Pages project creation and GitHub connection.

This script creates a Cloudflare Pages project and connects it to a GitHub repository,
configuring automatic deployments from the main branch.

Requirements:
- CLOUDFLARE_API_TOKEN environment variable (or set via --api-token)
- GitHub repository must exist and have at least one commit
- Cloudflare account ID (from dashboard or via --account-id)
"""

import os
import sys
import argparse
import json
import urllib.request
import urllib.error
from urllib.parse import urljoin

def get_api_token():
    """Get Cloudflare API token from environment or user input."""
    token = os.environ.get("CLOUDFLARE_API_TOKEN")
    if not token:
        print("Error: CLOUDFLARE_API_TOKEN not set. Set it or pass --api-token.", file=sys.stderr)
        sys.exit(1)
    return token

def cloudflare_api_request(method, path, token, body=None):
    """Make authenticated request to Cloudflare API."""
    base_url = "https://api.cloudflare.com/client/v4"
    url = urljoin(base_url + "/", path.lstrip("/"))
    
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }
    
    data = json.dumps(body).encode() if body else None
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    
    try:
        with urllib.request.urlopen(req) as response:
            result = json.loads(response.read().decode())
            if not result.get("success"):
                errors = result.get("errors", [{"message": "Unknown error"}])
                print(f"API Error: {errors[0].get('message')}", file=sys.stderr)
                return None
            return result.get("result")
    except urllib.error.HTTPError as e:
        error_body = e.read().decode()
        print(f"HTTP {e.code}: {error_body}", file=sys.stderr)
        return None

def create_pages_project(account_id, token, project_name):
    """Create a new Cloudflare Pages project."""
    print(f"Creating Pages project '{project_name}'...")
    result = cloudflare_api_request(
        "POST",
        f"/accounts/{account_id}/pages/projects",
        token,
        {"name": project_name, "production_branch": "main"}
    )
    if result:
        print(f"✓ Project created: {result.get('subdomain')}")
        return result.get("id")
    return None

def connect_github_source(account_id, token, project_id, repo_owner, repo_name, repo_id):
    """Connect a GitHub repository to the Pages project."""
    print(f"Connecting GitHub repository '{repo_owner}/{repo_name}'...")
    
    source_config = {
        "type": "github",
        "config": {
            "owner": repo_owner,
            "owner_id": None,  # Will be fetched if needed
            "repo_name": repo_name,
            "repo_id": str(repo_id),
            "production_branch": "main",
            "pr_comments_enabled": False,
            "deployments_enabled": True,
            "production_deployments_enabled": True,
            "preview_deployment_setting": "none",
            "preview_branch_includes": [],
            "preview_branch_excludes": [],
            "path_includes": ["*"],
            "path_excludes": []
        }
    }
    
    result = cloudflare_api_request(
        "POST",
        f"/accounts/{account_id}/pages/projects/{project_id}/source",
        token,
        source_config
    )
    if result:
        print(f"✓ GitHub connected: {repo_owner}/{repo_name} → main branch")
        return True
    return False

def configure_build_settings(account_id, token, project_id, build_command="", destination_dir="."):
    """Configure build settings for the Pages project."""
    print(f"Configuring build settings (output: {destination_dir})...")
    
    result = cloudflare_api_request(
        "PATCH",
        f"/accounts/{account_id}/pages/projects/{project_id}",
        token,
        {
            "build_config": {
                "build_command": build_command,
                "destination_dir": destination_dir
            }
        }
    )
    if result:
        print(f"✓ Build settings configured")
        return True
    return False

def main():
    parser = argparse.ArgumentParser(
        description="Set up Cloudflare Pages with GitHub integration"
    )
    parser.add_argument("--account-id", required=True, help="Cloudflare account ID")
    parser.add_argument("--repo-owner", required=True, help="GitHub repository owner")
    parser.add_argument("--repo-name", required=True, help="GitHub repository name")
    parser.add_argument("--repo-id", type=int, required=True, help="GitHub repository numeric ID")
    parser.add_argument("--project-name", help="Cloudflare Pages project name (defaults to repo name)")
    parser.add_argument("--api-token", help="Cloudflare API token (or use CLOUDFLARE_API_TOKEN env var)")
    parser.add_argument("--build-command", default="", help="Build command (default: empty for static HTML)")
    parser.add_argument("--output-dir", default=".", help="Build output directory (default: . for static files)")
    
    args = parser.parse_args()
    
    # Override env var if --api-token provided
    if args.api_token:
        os.environ["CLOUDFLARE_API_TOKEN"] = args.api_token
    
    token = get_api_token()
    project_name = args.project_name or args.repo_name
    
    print(f"\n🚀 Setting up Cloudflare Pages + GitHub")
    print(f"   Account: {args.account_id}")
    print(f"   Repository: {args.repo_owner}/{args.repo_name} (ID: {args.repo_id})")
    print(f"   Project: {project_name}\n")
    
    # Step 1: Create Pages project
    project_id = create_pages_project(args.account_id, token, project_name)
    if not project_id:
        print("Failed to create Pages project.", file=sys.stderr)
        sys.exit(1)
    
    # Step 2: Connect GitHub
    if not connect_github_source(args.account_id, token, project_id, args.repo_owner, args.repo_name, args.repo_id):
        print("Failed to connect GitHub repository.", file=sys.stderr)
        sys.exit(1)
    
    # Step 3: Configure build settings
    if not configure_build_settings(args.account_id, token, project_id, args.build_command, args.output_dir):
        print("Failed to configure build settings.", file=sys.stderr)
        sys.exit(1)
    
    print(f"\n✅ Setup complete!")
    print(f"   Project URL: https://{project_name}.pages.dev")
    print(f"   Dashboard: https://dash.cloudflare.com/?to=/:account/pages/view/{project_name}")
    print(f"\nNext steps:")
    print(f"1. Push to GitHub main branch to trigger first deployment")
    print(f"2. Monitor deployment in Cloudflare dashboard")
    print(f"3. Future pushes to main will automatically deploy\n")

if __name__ == "__main__":
    main()
