#!/usr/bin/env bash

# ============================================
# Lifecycle
# ============================================

function cmd::rename::on_load() {
  flag::register --name
  flag::register --type
  flag::register --new-name
  flag::register --new-type
}

# ============================================
# Help
# ============================================

function cmd::rename::help() {
  cat <<EOF
Usage: wgctl rename --name <name> --new-name <new-name>

Rename an existing WireGuard client.
The client IP and keys are preserved, only the name changes.

Options:
  --name <name>         Current client name (e.g. phone-phone-nuno)
  --new-name <name>     New client name (e.g. phone-nuno)

Examples:
  wgctl rename --name phone-phone-nuno --new-name phone-nuno
  wgctl mv --name laptop-old --new-name laptop-nuno
EOF
}

# ============================================
# Run
# ============================================

function cmd::rename::run() {
  local name=""
  local type=""
  local new_name=""
  local new_type=""

  while [[ $# -gt 0 ]]; do
    case "$1" in
      --name)     name="$2";          shift 2 ;;
      --type)     type="$2";          shift 2 ;;
      --new-name) new_name="$2";      shift 2 ;;
      --new-type) new_type="$2";      shift 2 ;;
      --help)     cmd::rename::help;  return  ;;
      *)
        log::error "Unknown flag: $1"
        cmd::rename::help
        return 1
        ;;
    esac
  done

  if [[ -z "$name" ]]; then
    log::error "Missing required flag: --name"
    cmd::rename::help
    return 1
  fi

  if [[ -z "$new_name" ]]; then
    log::error "Missing required flag: --new-name"
    cmd::rename::help
    return 1
  fi

  name=$(peers::resolve_and_require "$name" "$type") || return 1
  
  # Resolve new name if provided
  if [[ -n "$new_name" || -n "$new_type" ]]; then
    # If only new_type provided, keep same base name
    if [[ -z "$new_name" ]]; then
      new_name=$(echo "$name" | cut -d'-' -f2-)
    fi
    new_name=$(peers::resolve_name "$new_name" "$new_type") || return 1
  fi

  local dir
  dir="$(ctx::clients)"

  if [[ ! -f "${dir}/${name}.conf" ]]; then
    log::error "Client not found: ${name}"
    return 1
  fi

  if [[ -f "${dir}/${new_name}.conf" ]]; then
    log::error "Client already exists: ${new_name}"
    return 1
  fi

  log::section "Renaming client: ${name} → ${new_name}"

  # Rename client files
  mv "${dir}/${name}.conf"        "${dir}/${new_name}.conf"
  mv "${dir}/${name}_private.key" "${dir}/${new_name}_private.key"
  mv "${dir}/${name}_public.key"  "${dir}/${new_name}_public.key"

  log::fs_write "Renamed client files"

  # Update comment in wg0.conf
  sed -i "s/^# ${name}$/# ${new_name}/" "$(config::config_file)"

  log::fs_write "Updated server config"

  # Update block file if exists
  local block_file
  block_file="$(ctx::block::path "${name}.block")"
  if [[ -f "$block_file" ]]; then
    mv "$block_file" "$(ctx::block::path "${new_name}.block")"
    log::fs_write "Renamed block file"
  fi

  local old_meta new_meta
  old_meta=$(peers::meta_path "$name")
  new_meta=$(peers::meta_path "$new_name")
  [[ -f "$old_meta" ]] && mv "$old_meta" "$new_meta"

  # Reload WireGuard
  peers::reload

  log::wg_success "Client renamed: ${name} → ${new_name}"
}
