#!/usr/bin/env bash
set -euo pipefail
export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/homebrew/bin"

started_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
start_epoch="$(date +%s)"
state_dir="${CODEX_INSTALL_STATE_DIR:-${TMPDIR:-/tmp}/baijimu-codex-install}"
status_path="$state_dir/status.json"
result_path="$state_dir/result.json"
mkdir -p "$state_dir"

current_step=0
step_count=4
step1_name="Check ChatGPT desktop app"; step1_state="pending"; step1_detail=""
step2_name="Restart ChatGPT desktop app"; step2_state="pending"; step2_detail=""
step3_name="Verify process"; step3_state="pending"; step3_detail=""
step4_name="Verify visible window"; step4_state="pending"; step4_detail=""
target_app_path="/Applications/ChatGPT.app"
legacy_app_path="/Applications/Codex.app"

json_escape() {
  printf '%s' "${1:-}" | awk 'BEGIN { ORS = ""; first = 1 } {
    if (!first) { printf "\\n" }
    first = 0
    gsub(/\\/, "\\\\")
    gsub(/"/, "\\\"")
    gsub(/\r/, "\\r")
    gsub(/\t/, "\\t")
    printf "%s", $0
  }'
}

json_string() { printf '"'; json_escape "${1:-}"; printf '"'; }
write_install_console() { [ "${CODEX_INSTALL_QUIET:-}" = "1" ] && return 0; printf '%s\n' "$*" >&2; }

write_status() {
  {
    printf '{\n'
    printf '  "title": "Baijimu is verifying ChatGPT desktop app",\n'
    printf '  "platform": "macos",\n'
    printf '  "startedAt": '; json_string "$started_at"; printf ',\n'
    printf '  "updatedAt": '; json_string "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"; printf ',\n'
    printf '  "currentStep": %s,\n' "$current_step"
    printf '  "statusPath": '; json_string "$status_path"; printf ',\n'
    printf '  "resultPath": '; json_string "$result_path"; printf ',\n'
    printf '  "steps": [\n'
    for index in 1 2 3 4; do
      eval "name=\${step${index}_name}"
      eval "state=\${step${index}_state}"
      eval "detail=\${step${index}_detail}"
      printf '    { "index": %s, "name": ' "$index"; json_string "$name"; printf ', "state": '; json_string "$state"
      printf ', "detail": '; json_string "$detail"; printf ', "downloadedBytes": null, "totalBytes": null }'
      [ "$index" -lt "$step_count" ] && printf ','
      printf '\n'
    done
    printf '  ]\n'
    printf '}\n'
  } > "$status_path"
}

set_step() {
  index="$1"
  state="$2"
  detail="${3:-}"
  current_step="$index"
  eval "step${index}_state=\$state"
  eval "step${index}_detail=\$detail"
  write_status
  eval "name=\${step${index}_name}"
  if [ -n "$detail" ]; then
    write_install_console "[$index/$step_count] $name  $state  $detail"
  else
    write_install_console "[$index/$step_count] $name  $state"
  fi
}

finish_result() {
  ok="$1"
  app_started="$2"
  visible_window="$3"
  process_count="$4"
  lsappinfo_text="${5:-}"
  error_message="${6:-}"
  elapsed_ms="$(( ($(date +%s) - start_epoch) * 1000 ))"
  {
    printf '{\n'
    printf '  "ok": %s,\n' "$ok"
    printf '  "platform": "macos",\n'
    printf '  "startedAt": '; json_string "$started_at"; printf ',\n'
    printf '  "appInstalled": true,\n'
    printf '  "appStarted": %s,\n' "$app_started"
    printf '  "visibleWindow": %s,\n' "$visible_window"
    printf '  "processCount": %s,\n' "$process_count"
    printf '  "lsappinfo": '; json_string "$lsappinfo_text"; printf ',\n'
    printf '  "elapsedMs": %s,\n' "$elapsed_ms"
    if [ -n "$error_message" ]; then
      printf '  "warnings": [],\n'
      printf '  "errors": [ '; json_string "$error_message"; printf ' ]\n'
    else
      printf '  "warnings": [],\n'
      printf '  "errors": []\n'
    fi
    printf '}\n'
  } > "$result_path"
  cat "$result_path"
}

installed_app_path() {
  if [ -d "$target_app_path" ]; then
    printf '%s\n' "$target_app_path"
  elif [ -d "$legacy_app_path" ]; then
    printf '%s\n' "$legacy_app_path"
  fi
}

write_install_console ""
write_install_console "Baijimu is verifying ChatGPT desktop app"
write_install_console "Please keep this window open."
write_install_console ""
write_status

set_step 1 "running" "Checking ChatGPT desktop app bundle"
app_path="$(installed_app_path)"
if [ -z "$app_path" ]; then
  set_step 1 "failed" "ChatGPT desktop app is not installed"
  finish_result false false false 0 "" "ChatGPT desktop app is not installed"
  exit 1
fi
app_id="$(mdls -raw -name kMDItemCFBundleIdentifier "$app_path" 2>/dev/null || true)"
if [ -z "$app_id" ] || [ "$app_id" = "(null)" ]; then
  set_step 1 "failed" "ChatGPT desktop app bundle identifier is empty"
  finish_result false false false 0 "" "ChatGPT desktop app bundle identifier check failed"
  exit 1
fi
set_step 1 "completed" "ChatGPT desktop app bundle verified: $app_id"

set_step 2 "running" "Restarting ChatGPT desktop app"
pkill -f "$app_path/Contents/MacOS" 2>/dev/null || true
pkill -f "$app_path/Contents/Resources/codex app-server" 2>/dev/null || true
pkill -f "$app_path/Contents/Frameworks" 2>/dev/null || true
sleep 3
open "$app_path"
sleep 6
set_step 2 "completed" "ChatGPT desktop app opened"

set_step 3 "running" "Checking ChatGPT desktop app process"
process_output="$(pgrep -fl "$app_path/Contents/MacOS|codex app-server" || true)"
process_count="$(printf '%s\n' "$process_output" | awk 'NF { count++ } END { print count + 0 }')"
if [ "$process_count" -lt 1 ]; then
  set_step 3 "failed" "ChatGPT desktop app process was not found"
  finish_result false false false "$process_count" "" "ChatGPT desktop app process was not found"
  exit 1
fi
set_step 3 "completed" "ChatGPT desktop app process is running"

set_step 4 "running" "Checking visible ChatGPT Codex window"
info="$(/usr/bin/lsappinfo info -only pid,front,visible,windows "$app_id" 2>&1 || true)"
if printf '%s\n' "$info" | grep -q 'windows=\[ NULL \]'; then
  project="$HOME/Documents/Codex/$(date +%F)/default"
  mkdir -p "$project"
  open -a "$app_path" "$project" || true
  osascript -e "tell application id \"$app_id\" to activate" \
            -e "tell application id \"$app_id\" to reopen" 2>/dev/null || true
  sleep 5
  info="$(/usr/bin/lsappinfo info -only pid,front,visible,windows "$app_id" 2>&1 || true)"
fi

if printf '%s\n' "$info" | grep -q 'windows=\[ NULL \]'; then
  set_step 4 "failed" "ChatGPT desktop app started without a visible window"
  finish_result false true false "$process_count" "$info" "ChatGPT desktop app started without a visible window"
  exit 1
fi

set_step 4 "completed" "ChatGPT Codex window is visible"
write_install_console ""
write_install_console "ChatGPT desktop app verification completed. You can close this window."
finish_result true true true "$process_count" "$info" ""
