#!/usr/bin/env bash

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

# shellcheck source=lib/package.sh
source "$MODULE_NFS_SERVER_PROJECT_ROOT/lib/package.sh"
# shellcheck source=modules/network/nfs-server/config.sh
source "$MODULE_NFS_SERVER_DIR/config.sh"
# shellcheck source=modules/network/nfs-server/metadata.conf
source "$MODULE_NFS_SERVER_DIR/metadata.conf"

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

module_nfs_server_config_path() {
  printf '%s/%s\n' "$MODULE_NFS_SERVER_PROJECT_ROOT" "$POSTINSTALL_NFS_SERVER_EXPORTS_FILE"
}

module_nfs_server_entries() {
  local config_path=""
  config_path="$(module_nfs_server_config_path)"

  awk '
    function flush() {
      if (id != "") {
        print id "|" path "|" clients "|" options "|" description
      }
    }
    /^[[:space:]]*-[[:space:]]id:/ {
      flush()
      id=$0; sub(/.*id:[[:space:]]*/, "", id)
      path=clients=options=description=""
      next
    }
    /^[[:space:]]*path:/ { path=$0; sub(/.*path:[[:space:]]*/, "", path); next }
    /^[[:space:]]*clients:/ { clients=$0; sub(/.*clients:[[:space:]]*/, "", clients); next }
    /^[[:space:]]*options:/ { options=$0; sub(/.*options:[[:space:]]*/, "", options); next }
    /^[[:space:]]*description:/ { description=$0; sub(/.*description:[[:space:]]*/, "", description); next }
    END { flush() }
  ' "$config_path"
}

module_nfs_server_repo_lines() {
  local entry=""

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r export_id export_path clients options description <<< "$entry"
    printf '%s %s(%s)\n' "$export_path" "$clients" "$options"
  done < <(module_nfs_server_entries)
}

module_nfs_server_write_managed_file() {
  local temp_file="$1"

  {
    printf '# BEGIN postinstall-debian managed exports\n'
    cat "$temp_file"
    printf '# END postinstall-debian managed exports\n'
  } > "$POSTINSTALL_NFS_SERVER_EXPORT_FILE"
}

module_nfs_server_sync_add_only() {
  local line=""
  local current_content=""
  local temp_file=""

  mkdir -p /etc/exports.d
  temp_file="$(mktemp)"

  if [[ -f "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" ]]; then
    awk '
      /^# BEGIN postinstall-debian managed exports$/ { skip=1; next }
      /^# END postinstall-debian managed exports$/ { skip=0; next }
      !skip { print }
    ' "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" > "$temp_file"
  fi

  while IFS= read -r line; do
    [[ -n "$line" ]] || continue
    mkdir -p "${line%% *}"
    if ! grep -Fq "$line" "$temp_file"; then
      printf '%s\n' "$line" >> "$temp_file"
      log_info "Export NFS ajoute depuis le repo : $line"
      ui_success "Export NFS ajoute"
    else
      ui_info "Export NFS deja present : $line"
    fi
  done < <(module_nfs_server_repo_lines)

  module_nfs_server_write_managed_file "$temp_file"
  rm -f "$temp_file"
}

module_nfs_server_sync_strict() {
  local temp_file=""
  local line=""

  mkdir -p /etc/exports.d
  temp_file="$(mktemp)"

  while IFS= read -r line; do
    [[ -n "$line" ]] || continue
    mkdir -p "${line%% *}"
    printf '%s\n' "$line" >> "$temp_file"
  done < <(module_nfs_server_repo_lines)

  module_nfs_server_write_managed_file "$temp_file"
  rm -f "$temp_file"

  log_info "Exports NFS synchronises en mode strict"
  ui_success "Exports NFS synchronises en mode strict"
}

module_nfs_server_install() {
  local sync_mode="${1:-add-only}"

  package_refresh_indexes
  package_install nfs-kernel-server

  if [[ "$sync_mode" == "strict" ]]; then
    module_nfs_server_sync_strict
  elif [[ "$sync_mode" == "add-only" || "$sync_mode" == "repo" ]]; then
    module_nfs_server_sync_add_only
  else
    mkdir -p "$POSTINSTALL_NFS_SERVER_EXPORT_PATH"
    printf '%s %s(%s,sync,no_subtree_check)\n' "$POSTINSTALL_NFS_SERVER_EXPORT_PATH" "$POSTINSTALL_NFS_SERVER_CLIENTS" "$POSTINSTALL_NFS_SERVER_EXPORT_MODE" > "$POSTINSTALL_NFS_SERVER_EXPORT_FILE"
  fi

  exportfs -ra
  systemctl enable --now nfs-kernel-server
  systemctl restart nfs-kernel-server

  log_info "Serveur NFS synchronise depuis le repo"
  ui_success "Serveur NFS configure"
}

module_nfs_server_test() {
  package_is_installed nfs-kernel-server || return 1
  test -f "$POSTINSTALL_NFS_SERVER_EXPORT_FILE" || return 1
  test -f "$(module_nfs_server_config_path)" || return 1
}
