#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Shared cowork-flow command dispatcher."""

from __future__ import annotations

import os
import subprocess
import sys
from pathlib import Path

from common.core.execution_context import (
    ExecutionContextError,
    context_to_internal_cli_args,
    parse_public_execution_context_args,
)

COMMAND_SCRIPTS = {
    "resume": "commands/resume.py",
    "task": "commands/task.py",
    "change": "commands/change.py",
    "get-context": "commands/get_context.py",
    "get_context": "commands/get_context.py",
    "get-developer": "commands/get_developer.py",
    "get_developer": "commands/get_developer.py",
    "init-developer": "commands/init_developer.py",
    "init_developer": "commands/init_developer.py",
    "add-session": "commands/add_session.py",
    "add_session": "commands/add_session.py",
    "subagent": "commands/subagent.py",
    "doctor": "commands/doctor.py",
    "party-v2": "commands/party_mode_v2.py",
    "party_v2": "commands/party_mode_v2.py",
}

CONTEXT_AWARE_COMMANDS = {"resume", "task", "subagent"}


def print_usage() -> None:
    print(
        """Usage:
  ./.cowork-flow/run <command> [args...]
  ./.cowork-flow/run --context-file <assignment-context.json> <command> [args...]
  ./.cowork-flow/run --mode worker --task-dir <task-dir> --assignment <id> <command> [args...]
  ./.cowork-flow/run python [python-args...]

Common commands:
  resume
  task
  change
  get-context
  get-developer
  init-developer
  add-session
  subagent
  doctor
  party-v2
""".rstrip()
    )


def scripts_dir() -> Path:
    return Path(__file__).resolve().parent


def run_python(args: list[str], *, pythonpath: Path | None = None) -> int:
    env = None
    if pythonpath is not None:
        env = os.environ.copy()
        existing = env.get("PYTHONPATH")
        env["PYTHONPATH"] = (
            str(pythonpath)
            if not existing
            else f"{pythonpath}{os.pathsep}{existing}"
        )
    completed = subprocess.run([sys.executable, *args], check=False, env=env)
    return int(completed.returncode)


def run_script(script_name: str, args: list[str]) -> int:
    script_path = scripts_dir() / script_name
    if not script_path.is_file():
        print(f"Error: script not found: {script_path}", file=sys.stderr)
        return 2
    return run_python([str(script_path), *args], pythonpath=scripts_dir())


def main(argv: list[str] | None = None) -> int:
    raw_args = list(sys.argv[1:] if argv is None else argv)
    if not raw_args:
        print_usage()
        return 2

    try:
        context, args = parse_public_execution_context_args(raw_args)
    except ExecutionContextError as error:
        print(f"Error: {error}", file=sys.stderr)
        return 2
    if not args:
        print_usage()
        return 2

    command = args[0]
    rest = args[1:]
    if command in {"-h", "--help", "help"}:
        print_usage()
        return 0
    if command == "python":
        if not context.is_default:
            print(
                "Error: execution context flags are not supported with the `python` passthrough command.",
                file=sys.stderr,
            )
            return 2
        return run_python(rest, pythonpath=scripts_dir())

    script_name = COMMAND_SCRIPTS.get(command)
    if script_name is None:
        candidate = scripts_dir() / "commands" / f"{command}.py"
        if candidate.is_file():
            script_name = f"commands/{candidate.name}"
        else:
            print(f"Error: unknown cowork-flow command: {command}", file=sys.stderr)
            print_usage()
            return 2

    if not context.is_default and command not in CONTEXT_AWARE_COMMANDS:
        print(
            f"Error: execution context flags are only supported for: {', '.join(sorted(CONTEXT_AWARE_COMMANDS))}",
            file=sys.stderr,
        )
        return 2

    return run_script(script_name, [*context_to_internal_cli_args(context), *rest])


if __name__ == "__main__":
    sys.exit(main())
