#!/bin/sh
# *****************************************************************************
#                 __               ____                __
#                / /   ___  ____ _/ __/_____________ _/ /__
#               / /   / _ \/ __ `/ /_/ ___/ ___/ __ `/ / _ \
#              / /___/  __/ /_/ / __(__  ) /__/ /_/ / /  __/
#             /_____/\___/\__,_/_/ /____/\___/\__,_/_/\___/
#
#     (C)opyright 2025-2026, Leafscale, LLC -  https://www.leafscale.com
#
#     Project: zyginit
#    Filename: migrate-layout.sh
#     Authors: Chris Tusa <chris.tusa@leafscale.com>
#     License: CDDL-1.0
# Description: Migrate a 0.1.x /etc/zyginit/ flat layout to the 0.2.0
#              per-service directory layout. Idempotent. Dry-run by default.
#              Run with --apply to actually move files.
#
# *****************************************************************************

set -e

usage() {
    cat <<EOF
Usage: $0 [--dry-run|--apply] [--config-dir <path>]

  --dry-run         Print planned moves and exit (default)
  --apply           Perform the moves
  --config-dir DIR  Target directory (default /etc/zyginit/)
  -h, --help        Show this help
EOF
}

MODE=dry-run
CONFIG_DIR=/etc/zyginit

while [ $# -gt 0 ]; do
    case "$1" in
        --dry-run)    MODE=dry-run; shift ;;
        --apply)      MODE=apply; shift ;;
        --config-dir) CONFIG_DIR="$2"; shift 2 ;;
        -h|--help)    usage; exit 0 ;;
        *)            echo "error: unknown arg: $1" >&2; usage >&2; exit 2 ;;
    esac
done

if [ ! -d "$CONFIG_DIR" ]; then
    echo "error: $CONFIG_DIR is not a directory" >&2
    exit 1
fi

cd "$CONFIG_DIR"

# Ambiguity check: refuse if any service has BOTH <name>.toml at top level
# AND services/<name>/service.toml.
AMBIGUOUS=""
if [ -d services ]; then
    for f in *.toml; do
        [ -f "$f" ] || continue
        name="${f%.toml}"
        if [ -f "services/$name/service.toml" ]; then
            AMBIGUOUS="$AMBIGUOUS $name"
        fi
    done
fi
if [ -n "$AMBIGUOUS" ]; then
    echo "error: ambiguous layout — both old <name>.toml and services/<name>/service.toml exist for:$AMBIGUOUS" >&2
    echo "       Resolve manually before re-running." >&2
    exit 3
fi

# Plan moves
PLAN_FILE=$(mktemp /tmp/migrate-plan.XXXXXX)
trap 'rm -f "$PLAN_FILE"' EXIT

COUNT=0
for f in *.toml; do
    [ -f "$f" ] || continue
    name="${f%.toml}"
    echo "mkdir -p services/$name" >> "$PLAN_FILE"
    echo "mv $f services/$name/service.toml" >> "$PLAN_FILE"
    if [ -d "$name" ] && [ ! -L "$name" ]; then
        # Move helper scripts (start.sh, stop.sh, etc.) into the new dir
        for sf in "$name"/*; do
            [ -e "$sf" ] || continue
            base=$(basename "$sf")
            echo "mv $name/$base services/$name/$base" >> "$PLAN_FILE"
        done
        echo "rmdir $name" >> "$PLAN_FILE"
    fi
    COUNT=$((COUNT + 1))
done

# Plan enabled.d symlink retarget
if [ -d enabled.d ]; then
    for link in enabled.d/*; do
        [ -L "$link" ] || continue
        target=$(readlink "$link")
        case "$target" in
            *.toml)
                name=$(basename "$link")
                echo "ln -sfn ../services/$name $link" >> "$PLAN_FILE"
                ;;
        esac
    done
fi

# Plan examples/ migration (same convention as services/)
if [ -d examples ]; then
    for f in examples/*.toml; do
        [ -f "$f" ] || continue
        name=$(basename "${f%.toml}")
        echo "mkdir -p examples/$name" >> "$PLAN_FILE"
        echo "mv $f examples/$name/service.toml" >> "$PLAN_FILE"
    done
fi

if [ ! -s "$PLAN_FILE" ]; then
    echo "no changes — tree already in 0.2.0 layout"
    exit 0
fi

if [ "$MODE" = "dry-run" ]; then
    echo "PLANNED MOVES ($COUNT services):"
    cat "$PLAN_FILE"
    echo
    echo "Re-run with --apply to perform these moves."
    exit 0
fi

# Apply
echo "Applying $COUNT services..."
while IFS= read -r line; do
    eval "$line"
done < "$PLAN_FILE"
echo "Migration complete."
