#!/usr/bin/env python3

import argparse
import logging
import os
import socket
import sys
import time

from server import ZordonServer
from src.api.serverproxy_manager import ServerProxyManager

logger = logging.getLogger()

def main():
    parser = argparse.ArgumentParser(
        description="Zordon CLI tool for preparing/submitting a render job",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )

    # Required arguments
    parser.add_argument("scene_file", help="Path to the scene file (e.g., .blend, .max, .mp4)")
    parser.add_argument("engine", help="Desired render engine", choices=['blender', 'ffmpeg'])

    # Frame range
    parser.add_argument("--start", type=int, default=1, help="Start frame")
    parser.add_argument("--end", type=int, default=1, help="End frame")

    # Job metadata
    parser.add_argument("--name", default=None, help="Job name")

    # Output
    parser.add_argument("--output", default="", help="Output path/pattern (e.g., /renders/frame_####.exr)")

    # Target OS and Engine Version
    parser.add_argument(
        "--os",
        choices=["any", "windows", "linux", "macos"],
        default="any",
        help="Target operating system for render workers"
    )
    parser.add_argument(
        "--engine-version",
        default="latest",
        help="Required renderer/engine version number (e.g., '4.2', '5.0')"
    )

    # Optional flags
    parser.add_argument("--dry-run", action="store_true", help="Print job details without submitting")

    args = parser.parse_args()

    # Basic validation
    if not os.path.exists(args.scene_file):
        print(f"Error: Scene file '{args.scene_file}' not found!", file=sys.stderr)
        sys.exit(1)

    if args.start > args.end:
        print("Error: Start frame cannot be greater than end frame!", file=sys.stderr)
        sys.exit(1)

    # Calculate total frames
    total_frames = len(range(args.start, args.end + 1))
    job_name = args.name or os.path.basename(args.scene_file)
    file_path = os.path.abspath(args.scene_file)

    # Print job summary
    print("Render Job Summary:")
    print(f"  Job Name         : {job_name}")
    print(f"  Scene File       : {file_path}")
    print(f"  Engine           : {args.engine}")
    print(f"  Frames           : {args.start}-{args.end} → {total_frames} frames")
    print(f"  Output Path      : {args.output or '(default from scene)'}")
    print(f"  Target OS        : {args.os}")
    print(f"  Engine Version   : {args.engine_version}")

    if args.dry_run:
        print("\nDry run complete (no submission performed).")
        return

    local_hostname = socket.gethostname()
    local_hostname = local_hostname + (".local" if not local_hostname.endswith(".local") else "")
    found_proxy = ServerProxyManager.get_proxy_for_hostname(local_hostname)

    is_connected = found_proxy.check_connection()
    adhoc_server = None
    if not is_connected:
        adhoc_server = ZordonServer()
        adhoc_server.start_server()
        found_proxy = ServerProxyManager.get_proxy_for_hostname(adhoc_server.server_hostname)
        while not is_connected:
            # todo: add timeout
            is_connected = found_proxy.check_connection()
            time.sleep(1)

    new_job = {"name": job_name, "engine_name": args.engine}
    try:
        response = found_proxy.post_job_to_server(file_path, new_job)
    except Exception as e:
        print(f"Error creating job: {e}")
        exit(1)

    if response and response.ok:
        print(f"Uploaded to {found_proxy.hostname} successfully!")
        running_job_data = response.json()
        job_id = running_job_data.get('id')
        print(f"Job {job_id} Summary:")
        print(f"  Status           : {running_job_data.get('status')}")
        print(f"  Engine           : {running_job_data.get('engine_name')}-{running_job_data.get('engine_version')}")

        print("\nWaiting for render to complete...")
        percent_complete = 0.0
        while percent_complete < 1.0:
            # add checks for errors
            time.sleep(1)
            running_job_data = found_proxy.get_job_info(job_id)
            percent_complete = running_job_data['percent_complete']
            sys.stdout.write("\x1b[1A")  # Move up 1
            sys.stdout.write("\x1b[0J")  # Clear from cursor to end of screen (optional)
            print(f"Percent Complete: {percent_complete:.2%}")
            sys.stdout.flush()
        print("Finished rendering successfully!")
    else:
        print(f"Failed to upload job. {response.text} !")

    if adhoc_server:
        adhoc_server.stop_server()


if __name__ == "__main__":
    main()