#!/usr/bin/env bash

MODULE_SSH_SERVER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULE_SSH_SERVER_PROJECT_ROOT="$(cd "$MODULE_SSH_SERVER_DIR/../../.." && pwd)"

# shellcheck source=lib/package.sh
source "$MODULE_SSH_SERVER_PROJECT_ROOT/lib/package.sh"
# shellcheck source=modules/network/ssh-server/config.sh
source "$MODULE_SSH_SERVER_DIR/config.sh"
# shellcheck source=modules/network/ssh-server/metadata.conf
source "$MODULE_SSH_SERVER_DIR/metadata.conf"

module_ssh_server_metadata() {
  printf '%s|%s|%s\n' "$MODULE_ID" "$MODULE_NAME" "$MODULE_DESCRIPTION"
}

module_ssh_server_config_path() {
  printf '%s/%s\n' "$MODULE_SSH_SERVER_PROJECT_ROOT" "$POSTINSTALL_SSH_SETTINGS_FILE"
}

module_ssh_server_settings() {
  local config_path=""
  local port="$POSTINSTALL_SSH_PORT"
  local password_auth="$POSTINSTALL_SSH_PASSWORD_AUTH"
  local root_login="$POSTINSTALL_SSH_ROOT_LOGIN"

  config_path="$(module_ssh_server_config_path)"
  if [[ -f "$config_path" ]]; then
    while IFS='=' read -r key value; do
      case "$key" in
        port) port="$value" ;;
        password_authentication) password_auth="$value" ;;
        permit_root_login) root_login="$value" ;;
      esac
    done < <(
      awk '
        /^[[:space:]]*port:/ { print "port=" $2 }
        /^[[:space:]]*password_authentication:/ { print "password_authentication=" $2 }
        /^[[:space:]]*permit_root_login:/ { print "permit_root_login=" $2 }
      ' "$config_path"
    )
  fi

  printf '%s|%s|%s\n' "$port" "$password_auth" "$root_login"
}

module_ssh_server_validate_port() {
  local port="$1"

  [[ "$port" =~ ^[0-9]+$ ]] || return 1
  (( port >= 1 && port <= 65535 ))
}

module_ssh_server_require_package() {
  if package_is_installed "openssh-server"; then
    ui_info "Paquet openssh-server deja installe"
    return 0
  fi

  ui_warn "Paquet openssh-server absent, installation en cours"
  package_refresh_indexes
  package_install openssh-server
  log_info "Paquet openssh-server installe"
  ui_success "Paquet openssh-server installe"
}

module_ssh_server_write_config() {
  local ssh_port="${1:-$POSTINSTALL_SSH_PORT}"
  local password_auth="${2:-$POSTINSTALL_SSH_PASSWORD_AUTH}"
  local root_login="${3:-$POSTINSTALL_SSH_ROOT_LOGIN}"

  mkdir -p "$POSTINSTALL_SSH_CONFIG_DIR"
  cat > "$POSTINSTALL_SSH_CONFIG_FILE" <<EOF
# Fichier gere par postinstall-debian
Port $ssh_port
PasswordAuthentication $password_auth
PermitRootLogin $root_login
UsePAM yes
X11Forwarding no
EOF
}

module_ssh_server_check() {
  local ssh_port="${1:-$POSTINSTALL_SSH_PORT}"

  package_is_installed "openssh-server" || return 1
  systemctl is-active --quiet ssh || return 1
  ss -ltn 2>/dev/null | awk '{print $4}' | grep -Eq "(^|:)$ssh_port$"
}

module_ssh_server_install() {
  local settings=""
  local ssh_port=""
  local password_auth=""
  local root_login=""

  settings="$(module_ssh_server_settings)"
  IFS='|' read -r ssh_port password_auth root_login <<< "$settings"

  if ! module_ssh_server_validate_port "$ssh_port"; then
    ui_error "Port SSH invalide : $ssh_port"
    return 1
  fi

  module_ssh_server_require_package || return 1
  module_ssh_server_write_config "$ssh_port" "$password_auth" "$root_login"

  if command -v sshd >/dev/null 2>&1; then
    sshd -t || return 1
  fi

  systemctl enable --now ssh
  systemctl restart ssh

  log_info "Serveur SSH configure sur le port $ssh_port"
  ui_success "Serveur SSH configure sur le port $ssh_port"
}

module_ssh_server_test() {
  local settings=""
  local ssh_port=""

  settings="$(module_ssh_server_settings)"
  IFS='|' read -r ssh_port _ _ <<< "$settings"

  package_is_installed "openssh-server" || return 1
  command -v ssh >/dev/null 2>&1 || return 1
  test -f "$POSTINSTALL_SSH_CONFIG_FILE" || return 1
  test -f "$(module_ssh_server_config_path)" || return 1
  systemctl is-active --quiet ssh || return 1
  ss -ltn 2>/dev/null | awk '{print $4}' | grep -Eq "(^|:)$ssh_port$"
}
