#!/usr/bin/env python3
"""
Easypanel Deploy - Automated deployment via API

Authenticates with email/password, gets session token,
then deploys services following the exact workflow.

Usage:
    python3 deploy.py --project my-project --service my-service --git-url https://...
"""

import os
import sys
import json
import argparse
import requests
from pathlib import Path
from urllib.parse import quote


def load_env():
    """Load environment from .env file."""
    env_path = Path(__file__).parent / ".env"
    if env_path.exists():
        for line in env_path.read_text().splitlines():
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                k, v = line.split("=", 1)
                os.environ.setdefault(k.strip(), v.strip().strip("\"'"))


load_env()

EASYPANEL_URL = os.environ.get("EASYPANEL_URL", "https://panelwebsite.moreminimore.com")
EASYPANEL_USERNAME = os.environ.get("EASYPANEL_USERNAME")
EASYPANEL_PASSWORD = os.environ.get("EASYPANEL_PASSWORD")
EASYPANEL_DEFAULT_PROJECT = os.environ.get("EASYPANEL_DEFAULT_PROJECT", "default")


def get_session_token(email, password):
    """Authenticate with email/password and get session token."""
    if not email or not password:
        print("Error: EASYPANEL_USERNAME and EASYPANEL_PASSWORD required", file=sys.stderr)
        sys.exit(1)
    
    login_url = f"{EASYPANEL_URL}/api/trpc/auth.login"
    data = {"json": {"email": email, "password": password, "rememberMe": False}}
    
    try:
        response = requests.post(login_url, json=data)
        if response.status_code == 200:
            result = response.json()
            if "result" in result and "data" in result["result"]:
                session_data = result["result"]["data"]
                token = session_data.get("sessionToken") or session_data.get("token")
                if token:
                    return token
            session_token = response.cookies.get("sessionToken")
            if session_token:
                return session_token
        print(f"Error: Login failed ({response.status_code})", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def make_request(endpoint, method="GET", data=None, token=None):
    """Make tRPC-style API request to Easypanel."""
    url = f"{EASYPANEL_URL}/api/trpc/{endpoint}"
    headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
    
    try:
        if method == "GET":
            response = requests.get(url, headers=headers)
        elif method == "POST":
            response = requests.post(url, headers=headers, json=data)
        
        if response.status_code == 401:
            print(f"Error: Authentication failed (401)", file=sys.stderr)
            return None
        
        response.raise_for_status()
        result = response.json()
        if "result" in result:
            return result["result"].get("data")
        return result
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}", file=sys.stderr)
        return None


def create_service(project_name, service_name, token):
    print(f"🚀 Creating service: {service_name}")
    data = {"json": {"projectName": project_name, "serviceName": service_name, "build": {"type": "dockerfile", "file": "Dockerfile"}}}
    result = make_request("services.app.createService", "POST", data, token)
    if result:
        print(f"✅ Service created: {service_name}")
        return True
    print(f"❌ Failed to create service")
    return False


def update_git_source(project_name, service_name, git_url, branch="main", token=None):
    """Connect Git repository to service."""
    print(f"🔗 Connecting Git repository...")
    data = {"json": {"projectName": project_name, "serviceName": service_name, "repo": git_url, "ref": branch, "path": "/"}}
    result = make_request("services.app.updateSourceGit", "POST", data, token)
    if result:
        print(f"✅ Git repository connected: {git_url}")
        return True
    print(f"❌ Failed to connect Git repository")
    return False


def update_build_type(project_name, service_name, token, build_type="dockerfile"):
    print(f"🔨 Setting build type to {build_type}...")
    data = {"json": {"projectName": project_name, "serviceName": service_name, "build": {"type": build_type}}}
    result = make_request("services.app.updateBuild", "POST", data, token)
    if result:
        print(f"✅ Build type set: {build_type}")
        return True
    print(f"⚠️  Could not update build type (may already be set)")
    return True


def deploy_service(project_name, service_name, token):
    """Trigger deployment."""
    print(f"🎬 Triggering deployment...")
    data = {"json": {"projectName": project_name, "serviceName": service_name, "forceRebuild": False}}
    result = make_request("services.app.deployService", "POST", data, token)
    if result:
        print(f"✅ Deployment triggered")
        return True
    print(f"❌ Failed to trigger deployment")
    return False


def check_status(project_name, service_name, token):
    """Check deployment status."""
    print(f"📊 Checking status...")
    input_json = json.dumps({"json": {"projectName": project_name, "serviceName": service_name}})
    encoded_input = quote(input_json)
    result = make_request(f"services.app.inspectService?input={encoded_input}", "GET", None, token)
    if result:
        status = result.get("status", "unknown")
        print(f"📊 Status: {status}")
        if "url" in result:
            print(f"🌐 URL: {result['url']}")
        return status
    print(f"⚠️  Could not retrieve status")
    return "unknown"


def main():
    parser = argparse.ArgumentParser(description="Deploy to Easypanel")
    parser.add_argument("--project", required=True, help="Project name")
    parser.add_argument("--service", required=True, help="Service name")
    parser.add_argument("--git-url", required=True, help="Git repository URL")
    parser.add_argument("--branch", default="main", help="Git branch (default: main)")
    parser.add_argument("--port", type=int, default=80, help="Port (default: 80)")
    
    args = parser.parse_args()
    
    print("🚀 Easypanel Deploy")
    print("=" * 50)
    print(f"Project: {args.project}")
    print(f"Service: {args.service}")
    print(f"Git URL: {args.git_url}")
    print("=" * 50)
    print()
    
    print("🔐 Authenticating...")
    token = get_session_token(EASYPANEL_USERNAME, EASYPANEL_PASSWORD)
    if not token:
        print("❌ Authentication failed", file=sys.stderr)
        sys.exit(1)
    print("✅ Authenticated")
    print()
    
    if not create_service(args.project, args.service, token):
        print("⚠️  Service may already exist, continuing...")
    print()
    
    if not update_git_source(args.project, args.service, args.git_url, args.branch, token):
        sys.exit(1)
    print()
    
    if not update_build_type(args.project, args.service, token):
        sys.exit(1)
    print()
    
    if not deploy_service(args.project, args.service, token):
        sys.exit(1)
    print()
    
    print("⏳ Waiting for deployment to start...")
    import time
    time.sleep(5)
    
    status = check_status(args.project, args.service, token)
    
    print()
    print("=" * 50)
    if status in ["running", "ready", "building", "success"]:
        print("✅ Deployment successful!")
        print(f"Service: {args.service}")
        print(f"Project: {args.project}")
        print(f"Status: {status}")
    elif status == "failed":
        print("❌ Deployment failed!")
        print("Check logs in Easypanel dashboard")
        sys.exit(1)
    else:
        print("⚠️  Deployment status unknown")
        print("Check Easypanel dashboard for details")
    print("=" * 50)


if __name__ == "__main__":
    main()
