#!/usr/bin/env bash
#
# Migrate selected local-home config (.ipython, .condarc, ...) from host_old
# to host_new using PSI's "Partially Shared Home" feature, per:
# https://linux.psi.ch/documentation/user-guide/personal_drive/
#
# How this actually works on PSI Linux systems:
#   - Your personal (U:) drive and project drives are auto-mounted under
#     ~/network_drives/ (same network location on every Linux client -
#     nothing to copy between hosts for that part).
#   - Files like .ipython/.condarc live in the LOCAL home on each machine,
#     so they do NOT follow you between hosts automatically.
#   - The supported way to carry them over is: seed them once onto the
#     personal drive, then declare a `copy:` rule in
#     ~/network_drives/home/linux_home_links.yaml so any host (host_new
#     included) pulls them into its local home at login.
#
# This script:
#   1. checks/repairs the network_drives mount (setup-network-drives)
#   2. seeds the chosen local files/dirs onto the personal drive
#   3. adds/updates the corresponding `copy:` entries in linux_home_links.yaml
#      (only creates the file if missing - never silently rewrites an
#      existing one, since that could clobber your comments/other entries)
#   4. applies the change immediately via systemd --user
#   5. (informational only) looks for other NFS-style personal folders,
#      e.g. /sf/<instrument>/code/personal/<user>, that might also be worth
#      wiring in - unverified whether linux_home_links supports absolute
#      paths outside network_drives/home, so this only reports candidates
#      instead of touching them.
#
# Run this on host_old to seed + configure. Run steps 1 and 4 again (or just
# log in / ssh / `become <user>`) on host_new to pick the files up.

set -euo pipefail

# --- Managed items: local $HOME path -> name stored under linux_config/ ----
declare -A MANAGED_ITEMS=(
    [".ipython"]="ipython"
    [".condarc"]="condarc"
)
# ----------------------------------------------------------------------------

NETWORK_DRIVES="${HOME}/network_drives"
HOME_DRIVE="${NETWORK_DRIVES}/home"
CONFIG_DIR="${HOME_DRIVE}/linux_config"
LINKS_FILE_CANDIDATES=(
    "${HOME_DRIVE}/linux_home_links.yaml"
    "${HOME_DRIVE}/.linux_home_links.yaml"
)

log() { echo "==> $*"; }

ensure_network_drives() {
    if [[ ! -d "${HOME_DRIVE}" ]]; then
        log "network_drives/home not found - running setup-network-drives"
        setup-network-drives || true
    fi
    if [[ ! -d "${HOME_DRIVE}" ]]; then
        echo "ERROR: ${HOME_DRIVE} still missing. Run 'setup-network-drives'" >&2
        echo "manually, or open a ServiceNow ticket per the personal_drive docs." >&2
        exit 1
    fi
}

seed_configs() {
    mkdir -p "${CONFIG_DIR}"
    for local_name in "${!MANAGED_ITEMS[@]}"; do
        local src="${HOME}/${local_name}"
        local dest_name="${MANAGED_ITEMS[$local_name]}"
        local dest="${CONFIG_DIR}/${dest_name}"

        if [[ ! -e "${src}" ]]; then
            log "skip ${local_name}: not present in local home"
            continue
        fi

        if [[ -d "${src}" ]]; then
            log "seeding directory ${local_name} -> ${dest}/"
            mkdir -p "${dest}"
            rsync -a --delete "${src}/" "${dest}/"
        else
            log "seeding file ${local_name} -> ${dest}"
            cp -a "${src}" "${dest}"
        fi
    done
}

find_links_file() {
    for f in "${LINKS_FILE_CANDIDATES[@]}"; do
        [[ -f "$f" ]] && { echo "$f"; return 0; }
    done
    return 1
}

configure_links() {
    local links_file
    if links_file=$(find_links_file); then
        log "existing ${links_file} found - not auto-editing it to avoid"
        log "clobbering your comments/other entries. Make sure it contains:"
        print_snippet
        return 0
    fi

    links_file="${LINKS_FILE_CANDIDATES[0]}"
    log "creating ${links_file}"
    {
        echo "copy:"
        for local_name in "${!MANAGED_ITEMS[@]}"; do
            local dest_name="${MANAGED_ITEMS[$local_name]}"
            printf "  '%s':\n    from: 'network_drives/home/linux_config/%s'\n" \
                "${local_name}" "${dest_name}"
        done
    } > "${links_file}"
    cat "${links_file}"
}

print_snippet() {
    echo "---"
    echo "copy:"
    for local_name in "${!MANAGED_ITEMS[@]}"; do
        local dest_name="${MANAGED_ITEMS[$local_name]}"
        printf "  '%s':\n    from: 'network_drives/home/linux_config/%s'\n" \
            "${local_name}" "${dest_name}"
    done
    echo "---"
}

apply_links() {
    log "applying create-automatic-links-in-home.service"
    systemctl --user restart create-automatic-links-in-home.service || \
        log "could not restart the service here - it will run on next login/ssh/become"
}

discover_extra_nfs_locations() {
    log "looking for other NFS-style personal folders (informational only)"
    local found=0
    if [[ -d /sf ]]; then
        for f in /sf/*/code/personal/"${USER}"; do
            [[ -e "$f" ]] || continue
            echo "  candidate: $f"
            found=1
        done
    fi
    if [[ "$found" -eq 0 ]]; then
        echo "  none found under /sf/*/code/personal/${USER} on this host"
    fi
    echo "  NOTE: the personal_drive doc's copy/link examples only show"
    echo "  'network_drives/home/...' sources - it's unconfirmed whether"
    echo "  linux_home_links.yaml accepts absolute paths like the above."
    echo "  Verify with your sysadmin / the admin guide before relying on it."
}

main() {
    ensure_network_drives
    seed_configs
    configure_links
    apply_links
    discover_extra_nfs_locations
    log "done. On host_new: log in / ssh / 'become ${USER}' (or run this"
    log "script's ensure_network_drives+apply_links steps) to pick up the files."
}

main "$@"
