#!/usr/bin/env bash

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

# shellcheck source=lib/package.sh
source "$MODULE_NFS_CLIENT_PROJECT_ROOT/lib/package.sh"
# shellcheck source=modules/network/nfs-client/config.sh
source "$MODULE_NFS_CLIENT_DIR/config.sh"
# shellcheck source=modules/network/nfs-client/metadata.conf
source "$MODULE_NFS_CLIENT_DIR/metadata.conf"

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

module_nfs_client_config_path() {
  printf '%s/%s\n' "$MODULE_NFS_CLIENT_PROJECT_ROOT" "$POSTINSTALL_NFS_CLIENT_SHARES_FILE"
}

module_nfs_client_entries() {
  local config_path=""
  config_path="$(module_nfs_client_config_path)"

  awk '
    function flush() {
      if (id != "") {
        print id "|" name "|" description "|" server "|" remote_path "|" mount_path "|" access "|" mount_options "|" enabled
      }
    }
    /^[[:space:]]*-[[:space:]]id:/ {
      flush()
      id=$0; sub(/.*id:[[:space:]]*/, "", id)
      name=description=server=remote_path=mount_path=access=mount_options=enabled=""
      next
    }
    /^[[:space:]]*name:/ { name=$0; sub(/.*name:[[:space:]]*/, "", name); next }
    /^[[:space:]]*description:/ { description=$0; sub(/.*description:[[:space:]]*/, "", description); next }
    /^[[:space:]]*server:/ { server=$0; sub(/.*server:[[:space:]]*/, "", server); next }
    /^[[:space:]]*remote_path:/ { remote_path=$0; sub(/.*remote_path:[[:space:]]*/, "", remote_path); next }
    /^[[:space:]]*mount_path:/ { mount_path=$0; sub(/.*mount_path:[[:space:]]*/, "", mount_path); next }
    /^[[:space:]]*access:/ { access=$0; sub(/.*access:[[:space:]]*/, "", access); next }
    /^[[:space:]]*mount_options:/ { mount_options=$0; sub(/.*mount_options:[[:space:]]*/, "", mount_options); next }
    /^[[:space:]]*enabled_by_default:/ { enabled=$0; sub(/.*enabled_by_default:[[:space:]]*/, "", enabled); next }
    END { flush() }
  ' "$config_path"
}

module_nfs_client_default_ids() {
  local entry=""
  local ids=""

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r share_id _ _ _ _ _ _ _ enabled <<< "$entry"
    if [[ "$enabled" == "true" ]]; then
      ids="${ids:+$ids,}$share_id"
    fi
  done < <(module_nfs_client_entries)

  printf '%s\n' "$ids"
}

module_nfs_client_default_indices() {
  local entry=""
  local indices=""
  local index=1

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r share_id _ _ _ _ _ _ _ enabled <<< "$entry"
    if [[ "$enabled" == "true" ]]; then
      indices="${indices:+$indices,}$index"
    fi
    index=$((index + 1))
  done < <(module_nfs_client_entries)

  printf '%s\n' "$indices"
}

module_nfs_client_fstab_line() {
  local server="$1"
  local remote_path="$2"
  local mount_path="$3"
  local access="$4"
  local mount_options="$5"
  local options="$mount_options"

  if [[ "$access" == "ro" && "$options" != *ro* ]]; then
    options="${options},ro"
  elif [[ "$access" == "rw" && "$options" != *rw* ]]; then
    options="${options},rw"
  fi

  printf '%s:%s %s nfs %s 0 0' "$server" "$remote_path" "$mount_path" "$options"
}

module_nfs_client_enable_share() {
  local share_id="$1"
  local mount_now="${2:-no}"
  local entry=""
  local line=""

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
    [[ "$current_id" == "$share_id" ]] || continue

    mkdir -p "$mount_path"
    line="$(module_nfs_client_fstab_line "$server" "$remote_path" "$mount_path" "$access" "$mount_options")"
    if ! grep -Fq "$server:$remote_path $mount_path nfs" /etc/fstab; then
      printf '%s\n' "$line" >> /etc/fstab
      log_info "Partage NFS client ajoute a fstab : $share_id"
      ui_success "Partage NFS active : $share_id"
    else
      ui_info "Partage NFS deja present dans fstab : $share_id"
    fi

    if [[ "$mount_now" == "yes" ]]; then
      if command -v mountpoint >/dev/null 2>&1 && mountpoint -q "$mount_path"; then
        ui_info "Partage deja monte : $mount_path"
      elif mount "$mount_path"; then
        log_info "Partage NFS monte : $share_id"
        ui_success "Partage NFS monte : $share_id"
      else
        log_info "Echec du montage NFS : $share_id"
        ui_warn "Impossible de monter immediatement $mount_path"
      fi
    fi

    return 0
  done < <(module_nfs_client_entries)

  ui_warn "Partage NFS introuvable dans la configuration : $share_id"
  return 1
}

module_nfs_client_active_entries() {
  local entry=""

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
    if grep -Fq "$server:$remote_path $mount_path nfs" /etc/fstab; then
      printf '%s|%s|%s|%s|%s\n' "$current_id" "$name" "$mount_path" "$server:$remote_path" "$access"
    fi
  done < <(module_nfs_client_entries)
}

module_nfs_client_disable_share() {
  local share_id="$1"
  local entry=""
  local temp_file=""

  while IFS= read -r entry; do
    [[ -n "$entry" ]] || continue
    IFS='|' read -r current_id name description server remote_path mount_path access mount_options enabled <<< "$entry"
    [[ "$current_id" == "$share_id" ]] || continue

    if command -v mountpoint >/dev/null 2>&1 && mountpoint -q "$mount_path"; then
      if umount "$mount_path"; then
        log_info "Partage NFS demonte : $share_id"
        ui_success "Partage NFS demonte : $share_id"
      else
        log_info "Echec du demontage NFS : $share_id"
        ui_warn "Impossible de demonter $mount_path, suppression de l'entree fstab quand meme"
      fi
    fi

    temp_file="$(mktemp)"
    grep -Fv "$server:$remote_path $mount_path nfs" /etc/fstab > "$temp_file"
    cat "$temp_file" > /etc/fstab
    rm -f "$temp_file"

    log_info "Partage NFS retire de fstab : $share_id"
    ui_success "Partage NFS desactive : $share_id"
    return 0
  done < <(module_nfs_client_entries)

  ui_warn "Partage NFS introuvable dans la configuration : $share_id"
  return 1
}

module_nfs_client_install() {
  local action="${1:-enable}"
  local selected_ids="${2:-}"
  local mount_now="${3:-no}"
  local share_id=""

  package_refresh_indexes
  package_install nfs-common

  if [[ -n "$selected_ids" ]]; then
    while IFS= read -r share_id; do
      [[ -n "$share_id" ]] || continue
      if [[ "$action" == "disable" ]]; then
        module_nfs_client_disable_share "$share_id"
      else
        module_nfs_client_enable_share "$share_id" "$mount_now"
      fi
    done < <(printf '%s\n' "$selected_ids" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed '/^$/d')
  fi

  mkdir -p "$(dirname "$POSTINSTALL_NFS_CLIENT_STATE_FILE")"
  {
    printf 'ENABLED=yes\n'
    printf 'ACTION=%s\n' "$action"
    printf 'SHARES=%s\n' "$selected_ids"
    printf 'MOUNT_NOW=%s\n' "$mount_now"
  } > "$POSTINSTALL_NFS_CLIENT_STATE_FILE"
  log_info "Client NFS installe"
  ui_success "Client NFS installe"
}

module_nfs_client_test() {
  package_is_installed nfs-common || return 1
  command -v mount.nfs >/dev/null 2>&1 || return 1
  test -f "$(module_nfs_client_config_path)" || return 1
}
