#!/usr/bin/env bash
# =============================================================================
# Tank War Server — one-shot K8s deploy
#
# Mirrors the style of WarmCheck's run-deploy.sh:
#   1) sync source to master
#   2) build docker image on master
#   3) distribute image tarball to all worker nodes and `ctr` import
#   4) apply K8s manifests and restart the deployment
# =============================================================================
set -euo pipefail

# ---------- Configurable ------------------------------------------------------
# Host that the LOCAL developer machine can reach (uses your ssh_config alias).
MASTER_HOST="${MASTER_HOST:-host_172.16.16.16}"
# Intranet IPs that the MASTER uses to reach workers (no alias on the CVMs).
WORKER_INTRANET_IPS=(
  "10.1.0.6"
  "172.16.32.10"
  "172.16.32.16"
)

NAMESPACE="tankwar"
IMAGE_NAME="tankwar-server"
IMAGE_TAG="${IMAGE_TAG:-latest}"
REMOTE_WORKDIR="/root/tankwar"
SSH_USER="root"
SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10"

# ---------- Paths -------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
SERVER_DIR="${PROJECT_ROOT}/server"
K8S_DIR="${PROJECT_ROOT}/deploy/k8s"

# ---------- Helpers -----------------------------------------------------------
log()  { printf "\033[1;36m[deploy]\033[0m %s\n" "$*"; }
ok()   { printf "\033[1;32m[ ok  ]\033[0m %s\n" "$*"; }
warn() { printf "\033[1;33m[warn]\033[0m %s\n" "$*"; }
die()  { printf "\033[1;31m[fail]\033[0m %s\n" "$*" >&2; exit 1; }

ssh_master() { ssh ${SSH_OPTS} "${SSH_USER}@${MASTER_HOST}" "$@"; }
ssh_host()   { local h="$1"; shift; ssh ${SSH_OPTS} "${SSH_USER}@${h}" "$@"; }

# =============================================================================
# Step 1 — sync server source code & k8s manifests to master
# =============================================================================
step_sync() {
  log "1/5  Syncing source to master (${MASTER_HOST}) ..."
  ssh_master "mkdir -p ${REMOTE_WORKDIR}/server ${REMOTE_WORKDIR}/deploy/k8s"

  rsync -az --delete \
    --exclude '.git' \
    --exclude '.DS_Store' \
    -e "ssh ${SSH_OPTS}" \
    "${SERVER_DIR}/" \
    "${SSH_USER}@${MASTER_HOST}:${REMOTE_WORKDIR}/server/"

  rsync -az --delete \
    -e "ssh ${SSH_OPTS}" \
    "${K8S_DIR}/" \
    "${SSH_USER}@${MASTER_HOST}:${REMOTE_WORKDIR}/deploy/k8s/"

  ok "source synced"
}

# =============================================================================
# Step 2 — build docker image on master
# =============================================================================
step_build() {
  log "2/5  Building image ${IMAGE_NAME}:${IMAGE_TAG} on master ..."
  ssh_master "cd ${REMOTE_WORKDIR}/server && \
    docker build --pull -t ${IMAGE_NAME}:${IMAGE_TAG} -t ${IMAGE_NAME}:latest ."
  ok "image built"
}

# =============================================================================
# Step 3 — distribute image to every worker via containerd (ctr import)
#
# The cluster uses containerd directly (not docker-shim). Each node must
# have the image in the "k8s.io" namespace to be usable by kubelet.
# =============================================================================
step_distribute() {
  log "3/5  Distributing image to workers ..."

  # Export once on master
  local remote_tar="/tmp/${IMAGE_NAME}-${IMAGE_TAG}.tar"
  ssh_master "docker save ${IMAGE_NAME}:${IMAGE_TAG} -o ${remote_tar} && ls -lh ${remote_tar}"

  # Import on master's containerd (k8s.io ns) so the scheduler can use it locally too
  ssh_master "ctr -n k8s.io images import ${remote_tar} && \
              ctr -n k8s.io images tag --force docker.io/library/${IMAGE_NAME}:${IMAGE_TAG} \
                                              docker.io/library/${IMAGE_NAME}:latest"
  ok "master imported"

  # Fan-out to workers — executed FROM the master using intranet IPs.
  for ip in "${WORKER_INTRANET_IPS[@]}"; do
    log "    -> ${ip}"
    ssh_master "scp ${SSH_OPTS} ${remote_tar} ${SSH_USER}@${ip}:${remote_tar} && \
                ssh ${SSH_OPTS} ${SSH_USER}@${ip} 'ctr -n k8s.io images import ${remote_tar} && \
                    ctr -n k8s.io images tag --force docker.io/library/${IMAGE_NAME}:${IMAGE_TAG} \
                                                    docker.io/library/${IMAGE_NAME}:latest && \
                    rm -f ${remote_tar}'"
    ok "    ${ip} imported"
  done

  ssh_master "rm -f ${remote_tar}"
  ok "distribution done"
}

# =============================================================================
# Step 4 — apply manifests & roll the deployment
# =============================================================================
step_apply() {
  log "4/5  Applying K8s manifests ..."
  ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/namespace.yaml"
  ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/service.yaml"
  ssh_master "kubectl apply -f ${REMOTE_WORKDIR}/deploy/k8s/deployment.yaml"

  # Force a new rollout so we pick up the newly-imported image even
  # when the tag stays :latest.
  ssh_master "kubectl -n ${NAMESPACE} set image deploy/tankwar-server \
                tankwar-server=${IMAGE_NAME}:${IMAGE_TAG} --record=false || true"

  log "    waiting for rollout ..."
  ssh_master "kubectl -n ${NAMESPACE} rollout status deploy/tankwar-server --timeout=180s"
  ok "deployment is live"
}

# =============================================================================
# Step 5 — sanity check
# =============================================================================
step_verify() {
  log "5/5  Verifying ..."
  ssh_master "kubectl -n ${NAMESPACE} get pods,svc -o wide"
  echo
  ssh_master "kubectl -n ${NAMESPACE} logs deploy/tankwar-server --tail=20 || true"
  echo
  ok "all done. NodePort: 30081"
  cat <<EOF

------------------------------------------------------------
Public endpoints (after DNS on www.igeek.site takes effect):
  wss://www.igeek.site:30081/           (via NodePort)

Direct CVM access for smoke test:
  wscat -c ws://43.139.80.61:30081/

Remember to allow TCP/30081 in the CVM security group.
------------------------------------------------------------
EOF
}

main() {
  log "Tank War Server deploy — tag=${IMAGE_TAG}"
  step_sync
  step_build
  step_distribute
  step_apply
  step_verify
}

main "$@"
