#!/usr/bin/env bash
#
# Publish script for WolfPanel Agent releases.
# Copies built artifacts to downloads directories, updates latest.tar.gz,
# updates checksums.txt, and ensures older release versions are not deleted.
#
set -euo pipefail

# Locate directories
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

cd "${PROJECT_ROOT}"

# Check for VERSION file
if [ ! -f VERSION ]; then
  echo "Error: VERSION file not found in project root!" >&2
  exit 1
fi

VERSION=$(cat VERSION | tr -d '\r\n[:space:]')
if [ -z "${VERSION}" ]; then
  echo "Error: VERSION file is empty!" >&2
  exit 1
fi

DIST_DIR="dist"
ARCHIVE_NAME="wolfpanel-agent-${VERSION}.tar.gz"
ARCHIVE_PATH="${DIST_DIR}/${ARCHIVE_NAME}"
LATEST_JSON_PATH="${DIST_DIR}/latest.json"

# Check if build output exists
if [ ! -f "${ARCHIVE_PATH}" ]; then
  echo "Error: Build archive not found at ${ARCHIVE_PATH}!" >&2
  echo "Please run build-release.sh first." >&2
  exit 1
fi

# Locate and parse configuration file
CONFIG_PATH="deploy/release.conf"
if [ ! -f "${CONFIG_PATH}" ]; then
  echo "Error: Configuration file not found at ${CONFIG_PATH}!" >&2
  exit 1
fi

PUBLIC_ROOT=""
while IFS='=' read -r key value; do
  # Skip comments and empty lines
  [[ "$key" =~ ^#.* ]] && continue
  [[ -z "$key" ]] && continue
  
  if [ "$key" = "PUBLIC_ROOT" ]; then
    PUBLIC_ROOT=$(echo "$value" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//")
  fi
done < "${CONFIG_PATH}"

if [ -z "${PUBLIC_ROOT}" ]; then
  echo "Error: PUBLIC_ROOT is not defined in ${CONFIG_PATH}!" >&2
  exit 1
fi

# Parse channel
CHANNEL="${1:-stable}"
if [[ "$CHANNEL" != "stable" && "$CHANNEL" != "beta" && "$CHANNEL" != "dev" ]]; then
  echo "Error: Invalid channel '$CHANNEL'. Must be stable, beta, or dev." >&2
  exit 1
fi

TARGET_PARENT_DIR="${PUBLIC_ROOT}"
TARGET_CHANNEL_DIR="${PUBLIC_ROOT}/${CHANNEL}"

# Resolve a path to its canonical form (best effort; falls back to the literal).
real_path() {
  if command -v realpath >/dev/null 2>&1; then
    realpath "$1" 2>/dev/null || echo "$1"
  elif command -v readlink >/dev/null 2>&1; then
    readlink -f "$1" 2>/dev/null || echo "$1"
  else
    echo "$1"
  fi
}

# Copy a file into a directory, but skip if source and destination resolve to
# the same real path (prevents "cp: x and x are identical" self-copy failures
# when the repo is checked out under PUBLIC_ROOT on the downloads host).
safe_copy() {
  local src="$1" dest_dir="$2"
  local dest_file="${dest_dir%/}/$(basename "${src}")"
  if [ "$(real_path "${src}")" = "$(real_path "${dest_file}")" ]; then
    echo "Skipping copy: ${src} and ${dest_file} are the same file."
    return 0
  fi
  cp "${src}" "${dest_file}"
}

echo "Publishing WolfPanel Agent release v${VERSION} to channel: ${CHANNEL}..."
echo "Target channel directory: ${TARGET_CHANNEL_DIR}"

# Create target directories if they do not exist
mkdir -p "${TARGET_CHANNEL_DIR}"

# Copy versioned release files (do not delete old versions)
echo "Copying release files..."
safe_copy "${ARCHIVE_PATH}" "${TARGET_CHANNEL_DIR}"
if [ -f "${ARCHIVE_PATH}.sha256" ]; then
  safe_copy "${ARCHIVE_PATH}.sha256" "${TARGET_CHANNEL_DIR}"
fi
if [ -f "${LATEST_JSON_PATH}" ]; then
  safe_copy "${LATEST_JSON_PATH}" "${TARGET_CHANNEL_DIR}"
fi

# Overwrite latest.tar.gz in channel directory with this release (alias only)
echo "Updating latest.tar.gz alias..."
if [ "$(real_path "${ARCHIVE_PATH}")" = "$(real_path "${TARGET_CHANNEL_DIR}/latest.tar.gz")" ]; then
  echo "Skipping latest.tar.gz update: source and destination are the same file."
else
  cp "${ARCHIVE_PATH}" "${TARGET_CHANNEL_DIR}/latest.tar.gz"
fi

# Copy installer and uninstaller files to target parent directory (for downloads.wolfpanel.net/install.sh)
if [ -f "install.sh" ]; then
  echo "Publishing install.sh to ${TARGET_PARENT_DIR}/..."
  safe_copy "install.sh" "${TARGET_PARENT_DIR}"
fi
if [ -f "uninstall.sh" ]; then
  echo "Publishing uninstall.sh to ${TARGET_PARENT_DIR}/..."
  safe_copy "uninstall.sh" "${TARGET_PARENT_DIR}"
fi

# Update checksums.txt in channel directory
echo "Generating/updating checksums.txt in target directory..."
(
  cd "${TARGET_CHANNEL_DIR}"
  
  # Try to find a checksum tool
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum wolfpanel-agent-*.tar.gz latest.tar.gz > checksums.txt
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 wolfpanel-agent-*.tar.gz latest.tar.gz > checksums.txt
  else
    # Fallback to manual generation via openssl if other tools are missing
    rm -f checksums.txt
    for f in wolfpanel-agent-*.tar.gz latest.tar.gz; do
      if [ -f "$f" ]; then
        if command -v openssl >/dev/null 2>&1; then
          HASH=$(openssl dgst -sha256 "$f" | awk '{print $2}')
          echo "${HASH}  $f" >> checksums.txt
        else
          echo "Error: Cannot generate checksums.txt. No sha256 tools found!" >&2
          exit 1
        fi
      fi
    done
  fi
)

# Set safe permissions after publish if running on Linux
if [[ "$(uname -s)" == "Linux" ]]; then
  echo "Setting safe permissions (directories: 755, files: 644, scripts: 755) under ${TARGET_PARENT_DIR}..."
  find "${TARGET_PARENT_DIR}" -type d -exec chmod 755 {} +
  find "${TARGET_PARENT_DIR}" -type f -exec chmod 644 {} +
  if [ -f "${TARGET_PARENT_DIR}/install.sh" ]; then
    chmod 755 "${TARGET_PARENT_DIR}/install.sh"
  fi
  if [ -f "${TARGET_PARENT_DIR}/uninstall.sh" ]; then
    chmod 755 "${TARGET_PARENT_DIR}/uninstall.sh"
  fi
fi

echo "Publishing release completed successfully."
echo "Channel directory files:"
ls -la "${TARGET_CHANNEL_DIR}"
