#!/bin/bash
# deploy_pui_ui.sh — Deploy Profound UI files to the IBM i IFS
#
# Usage: deploy_pui_ui.sh <connection_name> <htdocs_path> <file_path_1> [file_path_2] ...

log() {
  echo "$(date -u +%Y-%m-%dT%H:%M:%S) $*"
}

CONNECTION="$1"
HTDOCS_PATH="$2"
shift 2

FILES=("$@")

if [ -z "${CONNECTION}" ]; then
  log "ERROR: Connection name is required"
  exit 1
fi

if [ -z "${HTDOCS_PATH}" ]; then
  log "ERROR: Target htdocs path is required"
  exit 1
fi

if [ ${#FILES[@]} -eq 0 ]; then
  log "WARNING: No files to deploy"
  exit 0
fi

SSH_CTRL_DIR=$(mktemp -d)
SSH_CTRL_PATH="${SSH_CTRL_DIR}/ctrl-%r@%h:%p"

SSH_BASE_OPTS=(
  -o "ControlPath=${SSH_CTRL_PATH}"
  -o ControlMaster=auto
  -o ControlPersist=yes
  -o StrictHostKeyChecking=accept-new
)

cleanup_ssh() {
  ssh "${SSH_BASE_OPTS[@]}" -O exit "${CONNECTION}" 2>/dev/null || true
  rm -rf "${SSH_CTRL_DIR}"
}
trap cleanup_ssh EXIT

run_ssh() {
  local cmd="$1"
  ssh "${SSH_BASE_OPTS[@]}" "${CONNECTION}" "${cmd}" < /dev/null
}

run_scp() {
  local source_file="$1"
  local target_path="$2"
  scp "${SSH_BASE_OPTS[@]}" -- "${source_file}" "${CONNECTION}:${target_path}"
}

log "Deploying ${#FILES[@]} file(s) to ${HTDOCS_PATH} via connection ${CONNECTION}"

if [ -n "${DEPLOY_SSH_USER}" ] && [ -n "${DEPLOY_SSH_PASSWORD}" ]; then
  if ! command -v sshpass >/dev/null 2>&1; then
    log "ERROR: sshpass is not installed. Prompted deploy requires a container image rebuild."
    exit 1
  fi

  SSH_HOST="${DEPLOY_SSH_HOST}"
  if [ -z "${SSH_HOST}" ]; then
    log "ERROR: DEPLOY_SSH_HOST is required when using prompted credentials"
    exit 1
  fi

  CONNECTION="${DEPLOY_SSH_USER}@${SSH_HOST}"
  export SSHPASS="${DEPLOY_SSH_PASSWORD}"
  SSH_BASE_OPTS+=(
    -o PreferredAuthentications=password
    -o PubkeyAuthentication=no
  )

  log "Opening SSH connection to ${SSH_HOST} as ${DEPLOY_SSH_USER} ..."
  output=$(sshpass -e ssh "${SSH_BASE_OPTS[@]}" -N -f "${CONNECTION}" 2>&1)
  sshpass_rc=$?
  if [ ${sshpass_rc} -eq 0 ]; then
    log "SSH connection established as ${DEPLOY_SSH_USER}"
  elif [ ${sshpass_rc} -eq 5 ]; then
    log "ERROR: Failed to authenticate as ${DEPLOY_SSH_USER}@${SSH_HOST}"
    echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
    exit 2
  else
    log "ERROR: Failed to open SSH connection as ${DEPLOY_SSH_USER} (exit code ${sshpass_rc})"
    echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
    exit 1
  fi

  unset DEPLOY_SSH_PASSWORD
  unset SSHPASS
else
  log "Opening SSH connection to ${CONNECTION} ..."
  output=$(ssh "${SSH_BASE_OPTS[@]}" -N -f "${CONNECTION}" 2>&1)
  ssh_rc=$?
  if [ ${ssh_rc} -eq 0 ]; then
    log "SSH connection established"
  else
    if echo "${output}" | grep -qi "permission denied\|authentication failed\|publickey"; then
      log "ERROR: Failed to authenticate to ${CONNECTION}"
      echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
      exit 2
    fi
    log "ERROR: Failed to open SSH connection to ${CONNECTION} (exit code ${ssh_rc})"
    echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
    exit 1
  fi
fi

SUCCEEDED=0
FAILED=0
TOTAL=${#FILES[@]}

for FILE in "${FILES[@]}"; do
  if [[ "${FILE}" != *"/htdocs/"* ]]; then
    log "ERROR: Skipping ${FILE} because it is not under an htdocs path"
    FAILED=$((FAILED + 1))
    continue
  fi

  RELATIVE_PATH="${FILE#*/htdocs/}"
  TARGET_PATH="${HTDOCS_PATH%/}/${RELATIVE_PATH}"
  TARGET_DIR=$(dirname "${TARGET_PATH}")

  printf -v QUOTED_TARGET_DIR '%q' "${TARGET_DIR}"
  printf -v QUOTED_TARGET_PATH '%q' "${TARGET_PATH}"

  log "Preparing ${TARGET_DIR}"
  if ! output=$(run_ssh "mkdir -p ${QUOTED_TARGET_DIR}" 2>&1); then
    log "ERROR: Failed to create ${TARGET_DIR}"
    echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
    FAILED=$((FAILED + 1))
    continue
  fi

  log "Copying ${FILE} -> ${TARGET_PATH}"
  if output=$(run_scp "${FILE}" "${QUOTED_TARGET_PATH}" 2>&1); then
    log "Deployed ${TARGET_PATH}"
    SUCCEEDED=$((SUCCEEDED + 1))
  else
    log "ERROR: Failed to copy ${FILE} -> ${TARGET_PATH}"
    echo "${output}" | while IFS= read -r line; do log "  ${line}"; done
    FAILED=$((FAILED + 1))
  fi
done

log "Deploy complete: ${SUCCEEDED} of ${TOTAL} file(s) deployed successfully"

if [ ${FAILED} -eq 0 ]; then
  exit 0
fi

exit 1
