#!/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-nuno)
  --new-name <name>     New client name (e.g. laptop-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="" type="" new_name="" 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
  new_name=$(peers::resolve_name "$new_name" "$new_type") || return 1

  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}"

  cmd::rename::_rename_files "$name" "$new_name"
  peers::reload

  # Update identity entry after successful rename
  identity::rename_peer "$name" "$new_name"

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

function cmd::rename::_rename_files() {
  local name="${1:-}" new_name="${2:-}"
  local dir
  dir="$(ctx::clients)"

  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"

  sed -i "s/^# ${name}$/# ${new_name}/" "$(config::config_file)"

  block::rename "$name" "$new_name"

  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"
}