#!/usr/bin/env bash

# This file is intended to be sourced by scripts in this directory.
# It centralizes the SSH/known_hosts logic so individual scripts stay small and consistent.

require_command() {
  local command_name="$1"
  if ! command -v "$command_name" >/dev/null 2>&1; then
    echo "required command not found: $command_name" >&2
    exit 1
  fi
}

agentteam_resolve_public_ip() {
  local stack_dir="$1"

  local public_ip="${AGENTTEAM_PUBLIC_IP:-}"
  if [[ -n "$public_ip" ]]; then
    printf '%s' "$public_ip"
    return 0
  fi

  if command -v terraform >/dev/null 2>&1; then
    terraform -chdir="$stack_dir" output -raw public_ip 2>/dev/null || true
  fi
}

agentteam_prepare_known_hosts() {
  local known_hosts_path="$1"

  mkdir -p "$(dirname "$known_hosts_path")"
  touch "$known_hosts_path"
}

agentteam_ssh_options=()
agentteam_known_hosts_path=''

agentteam_clear_known_host() {
  local known_hosts_path="$1"
  local host="$2"
  local port="$3"

  require_command ssh-keygen

  mkdir -p "$(dirname "$known_hosts_path")"
  touch "$known_hosts_path"
  ssh-keygen -R "[$host]:$port" -f "$known_hosts_path" >/dev/null 2>&1 || true
}

agentteam_build_ssh_options() {
  local ssh_private_key_path="$1"
  local ssh_port="$2"
  local known_hosts_path="$3"

  agentteam_known_hosts_path="$known_hosts_path"

  agentteam_ssh_options=(
    -i "$ssh_private_key_path"
    -o BatchMode=yes
    -o ConnectTimeout=10
    -o IdentitiesOnly=yes
    -o Port="$ssh_port"
    -o StrictHostKeyChecking=accept-new
    -o UserKnownHostsFile="$known_hosts_path"
  )
}

agentteam_wait_for_ssh() {
  local ssh_user="$1"
  local host="$2"
  local ssh_port="$3"
  local max_attempts="${4:-60}"
  local sleep_seconds="${5:-5}"

  require_command ssh

  local did_clear_host_key=0
  local last_error=''
  for ((attempt = 1; attempt <= max_attempts; attempt++)); do
    local output=''
    if output="$(ssh "${agentteam_ssh_options[@]}" "$ssh_user@$host" 'true' 2>&1)"; then
      return 0
    fi
    last_error="$output"

    if [[ "$did_clear_host_key" == "0" && -n "$agentteam_known_hosts_path" ]]; then
      if [[ "$output" == *"REMOTE HOST IDENTIFICATION HAS CHANGED"* || "$output" == *"Host key verification failed."* ]]; then
        echo "ssh host key mismatch detected for $host:$ssh_port; clearing known_hosts entry and retrying." >&2
        agentteam_clear_known_host "$agentteam_known_hosts_path" "$host" "$ssh_port"
        did_clear_host_key=1
        continue
      fi
    fi

    if [[ "$output" == *"Permission denied (publickey"* ]]; then
      echo "ssh authentication failed for $ssh_user@$host:$ssh_port (publickey)." >&2
      echo "hint: unlock the SSH key via ssh-agent/keychain, or set AGENTTEAM_SSH_PRIVATE_KEY_PATH to an unencrypted key." >&2
      echo "" >&2
      echo "ssh error:" >&2
      echo "$output" >&2
      return 1
    fi

    if [[ "$attempt" == "$max_attempts" ]]; then
      echo "timed out waiting for SSH on $host:$ssh_port" >&2
      if [[ -n "$last_error" ]]; then
        echo "" >&2
        echo "last ssh error:" >&2
        echo "$last_error" >&2
      fi
      return 1
    fi
    sleep "$sleep_seconds"
  done
}

agentteam_ssh() {
  require_command ssh
  ssh "${agentteam_ssh_options[@]}" "$@"
}

agentteam_scp() {
  require_command scp
  scp "${agentteam_ssh_options[@]}" "$@"
}
