#!/usr/bin/env bash
set -euo pipefail

root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
export PYTHONUTF8="${PYTHONUTF8:-1}"
export PYTHONIOENCODING="${PYTHONIOENCODING:-utf-8}"

resolve_python() {
  local candidate
  for candidate in \
    "${HEPHAESTUS_PYTHON:-}" \
    "$root/bin/python3" \
    python3 \
    python
  do
    [[ -n "$candidate" ]] || continue
    if "$candidate" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 9) else 1)' >/dev/null 2>&1; then
      printf '%s\n' "$candidate"
      return 0
    fi
  done
  if command -v py >/dev/null 2>&1 && py -3 -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 9) else 1)' >/dev/null 2>&1; then
    printf '%s\n' "py -3"
    return 0
  fi
  return 1
}

HEPHAESTUS_PY="$(resolve_python || true)"

run_python_module() {
  if [[ -z "$HEPHAESTUS_PY" ]]; then
    echo "hephaestus: Python 3.9+ not found. On Windows, install Python from python.org or run 'py -3' once, then rerun hephaestus doctor." >&2
    exit 127
  fi
  # shellcheck disable=SC2086
  HEPHAESTUS_RUNTIME_ROOT="$root" PYTHONPATH="$root${PYTHONPATH:+:$PYTHONPATH}" $HEPHAESTUS_PY -c 'import os, runpy, sys; cwd=os.getcwd(); root=os.environ["HEPHAESTUS_RUNTIME_ROOT"]; sys.path=[p for p in sys.path if p not in ("", cwd, root)]; sys.path.insert(0, root); sys.argv=sys.argv[1:]; runpy.run_module(sys.argv[0], run_name="__main__", alter_sys=True)' "$@"
}

upload_question() {
  cat <<'EOF'
Cloud에 업로드 할까요? 다른사람들이 볼 수 없어요.
Upload to Cloud? Other people cannot see it.

Agentlas Hub에 업로드 할까요? 다른 사람들이 빌려 쓸 수 있어요.
Upload to Agentlas Hub? Other people can borrow it.

1) Cloud
2) Agentlas Hub
EOF
}

resolve_upload_folder() {
  local arg candidate
  for arg in "$@"; do
    candidate="${arg#file://}"
    candidate="${candidate%\"}"
    candidate="${candidate#\"}"
    if [[ -d "$candidate" ]]; then
      (cd "$candidate" && pwd)
      return 0
    fi
    if [[ -d "$PWD/$candidate" ]]; then
      (cd "$PWD/$candidate" && pwd)
      return 0
    fi
  done
  return 1
}

run_upload_gate() {
  local target choice visibility arg
  local -a folder_args publish_args
  while [[ "$#" -gt 0 ]]; do
    arg="$1"
    case "$arg" in
      --visibility)
        if [[ "$#" -lt 2 || "${2:-}" == --* ]]; then
          echo "Missing value for --visibility. Use private-link or marketplace." >&2
          return 2
        fi
        visibility="${2:-}"
        shift 2
        ;;
      --visibility=*)
        visibility="${arg#--visibility=}"
        shift
        ;;
      --cloud|cloud|private|private-link)
        visibility="${visibility:-private-link}"
        shift
        ;;
      --hub|hub|marketplace|public|agentlas-hub)
        visibility="${visibility:-marketplace}"
        shift
        ;;
      --dry-run|--no-open)
        publish_args+=("$arg")
        shift
        ;;
      --slug|--base-url)
        if [[ "$#" -lt 2 || "${2:-}" == --* ]]; then
          echo "Missing value for $arg." >&2
          return 2
        fi
        publish_args+=("$arg" "${2:-}")
        shift 2
        ;;
      --slug=*|--base-url=*)
        publish_args+=("$arg")
        shift
        ;;
      *)
        folder_args+=("$arg")
        shift
        ;;
    esac
  done
  case "${visibility:-}" in
    "" ) ;;
    cloud|private|private-link)
      visibility="private-link"
      ;;
    hub|marketplace|public|agentlas-hub)
      visibility="marketplace"
      ;;
    *)
      echo "Unknown upload visibility: $visibility. Use private-link or marketplace." >&2
      return 2
      ;;
  esac
  if [[ -n "${visibility:-}" ]]; then
    if ! target="$(resolve_upload_folder "${folder_args[@]}")"; then
      echo "업로드 대상 에이전트 폴더를 찾지 못했습니다. /hep-upload <agent-folder> --visibility <private-link|marketplace> 형태로 다시 실행하세요." >&2
      return 2
    fi
    run_python_module agentlas_cloud publish "$target" --visibility "$visibility" "${publish_args[@]}"
    return $?
  fi
  upload_question
  if [[ ! -t 0 ]]; then
    echo "No upload performed. Choose Cloud or Agentlas Hub in the chat, then run one explicit command:" >&2
    echo "  hep-upload <agent-folder> --visibility private-link   # Cloud" >&2
    echo "  hep-upload <agent-folder> --visibility marketplace    # Agentlas Hub" >&2
    return 0
  fi
  printf 'Select 1 or 2: ' >&2
  read -r choice
  if ! target="$(resolve_upload_folder "${folder_args[@]}")"; then
    echo "업로드 대상 에이전트 폴더를 찾지 못했습니다. /hep-upload <agent-folder> 형태로 다시 실행하세요." >&2
    return 2
  fi
  case "$(printf '%s' "$choice" | tr '[:upper:]' '[:lower:]')" in
    1|cloud|c)
      run_python_module agentlas_cloud publish "$target" --visibility private-link "${publish_args[@]}"
      ;;
    2|hub|agentlas\ hub|agentlas|h)
      run_python_module agentlas_cloud publish "$target" --visibility marketplace "${publish_args[@]}"
      ;;
    *)
      echo "Upload cancelled. Choose 1 for Cloud or 2 for Agentlas Hub." >&2
      return 2
      ;;
  esac
}

usage() {
  cat <<'EOF'
Usage:
  bin/hephaestus ontology [--gui] [--no-open] [project-dir]
  bin/hephaestus ontology add <path> [--project <dir>] [--kind company|project|personal] [--scope public|internal|private]
  bin/hephaestus wizard <agent-folder> [--name <name>]
  bin/hephaestus security scan <agent-folder> [--strict] [--acknowledge-warn] [--llm-judgment <path>]
  bin/hephaestus runtime bundle <agent-folder>
  bin/hephaestus runtime read-agent-file <agent-folder> <path>
  bin/hephaestus package <agent-folder> [--visibility marketplace|private-link]
  bin/hephaestus publish <agent-folder> [--visibility marketplace|private-link] [--dry-run]
  bin/hephaestus field-test
	  bin/hephaestus auth status|login|ensure|logout [--base-url <url>]
	  bin/hephaestus doctor
  bin/hephaestus update [--check]
  bin/hephaestus plugins list [--project <dir>]
  bin/hephaestus plugins resolve "<need>" [--project <dir>] [--no-hub]
  bin/hephaestus meta-agent "<request>"
  bin/hephaestus hep-build "<request>"             # build/create/package surface
  bin/hephaestus build "<request>"                 # shorthand for hep-build
  bin/hephaestus network init|status|reindex|bench
  bin/hephaestus network add-source <path> | remove-source <path>
  bin/hephaestus network grant <capability> --target <id> [--scope ...]
  bin/hephaestus cards lint [path] | cards migrate <root> --tier restricted|private|plugin|local
  bin/hephaestus ao lint [dir] | ao graph [--agent <agent>] [dir] | ao query "<query>" [dir]
  bin/hephaestus ao plan <from> <to> [--max-depth N] [dir]
  bin/hephaestus ao diff [dir] | ao migrate [dir] [--no-write] [--overwrite]
  bin/hephaestus route "<request>" [--project <dir>] [--no-hub] [--approve-hub] [--hub-only] [--scope network|cloud] [--caller <agent-id>]
  bin/hephaestus local-gui "<shortcut>" [--detach] [--no-open]   # restore/open packaged GUI shortcuts
  bin/hephaestus hep-network "<request>"           # public Hub / temporary TF surface
  bin/hephaestus stormbreaker run "<request>" [--background] [--executor-command <cmd>] [--research-evidence] [--research-loadout auto|safe|public-web|social|browser|full|recommended]  # auto-run pipeline packets
  bin/hephaestus hep-storm "<request>" [--background] [--executor-command <cmd>] [--research-evidence] [--research-loadout auto|safe|public-web|social|browser|full|recommended]  # shorthand
  bin/hephaestus hep-cloud "<request>" [--project <dir>] [--no-hub]   # search ONLY my own cloud packages (보관함)
  bin/hephaestus hep-search "<request>" [--limit 10]     # show cloud + Hub candidates only
  bin/hephaestus research doctor|status|credentials|modules|armory|profile|bridge-contract|bridge-check|platform-contract|platform-check|loadouts | research plan <url> [--loadout public-web|browser] [--depth deep] | research gather "<query>" [--variant docs] [--follow-results 3] | research search "<query>" [--variant reddit] [--loadout safe|public-web|social] | research read <url> [--loadout public-web|browser] [--depth deep] [--max-weight browser_heavy]  # lightweight Research Engine
  bin/hephaestus hep-call "agent-a,agent-b" "<context>"  # prepare named Hub/cloud agents
  bin/hephaestus hep-upload <agent-folder>          # ask Cloud vs Hub before upload
  bin/hephaestus mcp serve              # stdio MCP server (hephaestus_route tool)

Examples:
  bin/hephaestus ontology
  bin/hephaestus ontology --gui .
  bin/hephaestus ontology add ./company-docs --kind company --scope private
  bin/hephaestus wizard ./some-agent --name instagram-operator
  bin/hephaestus security scan ./some-agent --strict
  bin/hephaestus runtime bundle ./some-agent
EOF
}

if [[ "${1:-}" == "" || "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
  usage
  exit 0
fi

command="$1"
shift

case "$command" in
	  ontology)
	    if [[ "${1:-}" == "add" ]]; then
	      shift
	      run_python_module ontology sources add "$@"
	      exit $?
	    fi

    open_flag=1
    if [[ "${1:-}" == "--gui" ]]; then
      shift
    fi
    if [[ "${1:-}" == "--no-open" ]]; then
      open_flag=0
      shift
    fi
	    project="${1:-.}"
	    if [[ "$open_flag" == "1" ]]; then
	      run_python_module ontology gui "$project"
	    else
	      run_python_module ontology gui "$project" --no-open
	    fi
	    ;;
	  wizard)
	    run_python_module agentlas_cloud wizard "$@"
	    ;;
	  security)
	    run_python_module agentlas_cloud security "$@"
	    ;;
  runtime)
    runtime_sub="${1:-}"
    shift || true
    case "$runtime_sub" in
	      bundle)
	        run_python_module agentlas_cloud bundle "$@"
	        ;;
	      read-agent-file)
	        run_python_module agentlas_cloud read-agent-file "$@"
	        ;;
      *)
        echo "hephaestus: unknown runtime command: $runtime_sub" >&2
        usage >&2
        exit 2
        ;;
    esac
    ;;
	  field-test)
	    run_python_module agentlas_cloud field-test
	    ;;
	  auth)
	    run_python_module agentlas_cloud auth "$@"
	    ;;
	  doctor)
	    run_python_module agentlas_cloud doctor "$@"
	    ;;
	  update)
	    run_python_module agentlas_cloud update "$@"
	    ;;
	  plugins)
	    run_python_module agentlas_cloud plugins "$@"
	    ;;
  meta-agent|hep-build|hephaestus-build|Hephaestus-build|build)
    request="${*:-Create or package an Agentlas-compatible agent.}"
    cat <<EOF
Hephaestus meta-agent request:
$request

Open Claude Code or Codex with the installed plugin, then run:
/hep-build $request
EOF
    ;;
	  network|cards|ao|route|mcp|local-gui|package|publish)
	    run_python_module agentlas_cloud "$command" "$@"
	    ;;
	  hep-network|hephaestus-network|hephaests-network)
	    if [[ "${HEPHAESTUS_NETWORK_GUI_SHORTCUTS:-1}" != "0" ]]; then
	      set +e
	      gui_args=("$@" "--detach")
	      if [[ "${HEPHAESTUS_NETWORK_GUI_NO_OPEN:-0}" == "1" ]]; then
	        gui_args+=("--no-open")
	      fi
	      gui_output="$(run_python_module agentlas_cloud local-gui "${gui_args[@]}" 2>/dev/null)"
	      gui_status=$?
	      set -e
	      if [[ "$gui_status" == "0" ]]; then
	        printf '%s\n' "$gui_output"
	        exit 0
	      elif [[ "$gui_status" != "4" ]]; then
	        printf '%s\n' "$gui_output"
	        exit "$gui_status"
	      fi
	    fi
	    if [[ "${HEPHAESTUS_NETWORK_AUTO_RUN:-1}" == "0" ]]; then
	      run_python_module agentlas_cloud route "$@" --hub-only --scope network
	    else
	      run_python_module agentlas_cloud route "$@" --hub-only --scope network --auto-run --background
	    fi
	    ;;
		  stormbreaker)
		    run_python_module agentlas_cloud stormbreaker "$@"
		    ;;
		  hep-storm|hephaestus-storm|storm)
		    run_python_module agentlas_cloud stormbreaker run "$@"
		    ;;
		  search|hep-search|hephaestus-search|Hephaestus-search)
		    run_python_module agentlas_cloud search "$@"
		    ;;
		  research)
		    run_python_module agentlas_cloud research "$@"
		    ;;
		  call|hep-call|hephaestus-call|Hephaestus-call)
		    run_python_module agentlas_cloud call "$@"
		    ;;
		  cloud|hep-cloud|hephaestus-cloud)
		    # /hep-cloud: route through the owner's OWN cloud packages only
		    # (보관함). Reuses the route command with the cloud scope (owner-scoped
		    # Hub query; implies --hub-only).
		    run_python_module agentlas_cloud route "$@" --scope cloud
		    ;;
      upload|hep-upload|hephaestus-upload)
        run_upload_gate "$@"
        ;;
  -*)
    echo "hephaestus: unknown command: $command" >&2
    usage >&2
    exit 2
    ;;
	  *)
	    # Natural-language shorthand: hephaestus "<request>" routes through the network router.
	    run_python_module agentlas_cloud route "$command $*" --allow-local-routing
	    ;;
esac
