#!/bin/bash
# =============================================================
# manage-endpoints.sh - Gestione endpoint macless-haystack
#
# Script per aggiungere, autenticare e gestire gli endpoint
# FindMy macless-haystack con persistenza UUID automatica.
#
# Uso:
#   ./manage-endpoints.sh add 5 8       # Aggiunge endpoint 5,6,7,8
#   ./manage-endpoints.sh auth 5        # Autentica endpoint 5
#   ./manage-endpoints.sh status        # Mostra stato tutti gli endpoint
#   ./manage-endpoints.sh compose 8     # Genera docker-compose per N endpoint
#   ./manage-endpoints.sh update-daemon 8  # Aggiorna il servizio systemd per N endpoint
#
# Ogni endpoint:
#   - Ha una porta dedicata: 6175 + N (EP5=6180, EP6=6181, ...)
#   - Usa un account Apple separato (auth.json)
#   - Persiste UUID al riavvio (startup-endpoint.sh)
#   - Dati in /var/www/SganaTags/Apple-Project/endpointN/data/
# =============================================================

set -e

BASE_DIR="/var/www/SganaTags/Apple-Project"
COMPOSE_DIR="$BASE_DIR/docker-findmy"
SERVICE_NAME="sganatags_webhookReports_rollingkeys"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

print_header() {
    echo ""
    echo -e "${CYAN}============================================================${NC}"
    echo -e "${CYAN}  $1${NC}"
    echo -e "${CYAN}============================================================${NC}"
}

get_ep_dir() {
    local num=$1
    if [ "$num" -eq 1 ]; then
        echo "endpoint"
    else
        echo "endpoint${num}"
    fi
}

get_ep_port() {
    local num=$1
    echo $((6175 + num))
}

detect_ownership() {
    local ref_dir=""
    for d in "$BASE_DIR"/endpoint*/data; do
        if [ -d "$d" ]; then
            ref_dir="$d"
            break
        fi
    done

    if [ -z "$ref_dir" ]; then
        ref_dir="$BASE_DIR"
    fi

    EP_OWNER=$(stat -c '%U' "$ref_dir" 2>/dev/null || stat -f '%Su' "$ref_dir" 2>/dev/null || echo "www-data")
    EP_GROUP=$(stat -c '%G' "$ref_dir" 2>/dev/null || stat -f '%Sg' "$ref_dir" 2>/dev/null || echo "www-data")
}

# ----- ADD: Crea directory per nuovi endpoint -----
cmd_add() {
    local from=$1
    local to=$2

    if [ -z "$from" ] || [ -z "$to" ]; then
        echo "Uso: $0 add <da> <a>"
        echo "  Es: $0 add 5 8   (crea endpoint 5,6,7,8)"
        exit 1
    fi

    print_header "Creazione endpoint $from - $to"

    detect_ownership
    echo -e "  Permessi rilevati: ${CYAN}${EP_OWNER}:${EP_GROUP}${NC} (da endpoint esistenti)"
    echo ""

    for num in $(seq "$from" "$to"); do
        local dir_name=$(get_ep_dir "$num")
        local data_dir="$BASE_DIR/$dir_name/data"
        local port=$(get_ep_port "$num")

        if [ -d "$data_dir" ]; then
            echo -e "  ${YELLOW}[EP$num]${NC} $dir_name/data/ esiste gia' (porta $port)"
        else
            mkdir -p "$data_dir"
            chown -R "${EP_OWNER}:${EP_GROUP}" "$BASE_DIR/$dir_name"
            chmod -R g+rwX "$BASE_DIR/$dir_name"
            find "$BASE_DIR/$dir_name" -type d -exec chmod g+s {} \;
            echo -e "  ${GREEN}[EP$num]${NC} Creato $dir_name/data/ (porta $port) [${EP_OWNER}:${EP_GROUP}]"
        fi
    done

    echo ""
    echo -e "${GREEN}Directory create.${NC} Prossimi passi:"
    echo "  1. Autentica ogni endpoint:  $0 auth <N>"
    echo "  2. Aggiorna docker-compose:  $0 compose $to"
    echo "  3. Aggiorna daemon systemd:  $0 update-daemon $to"
    echo "  4. Rilancia i container:     cd $COMPOSE_DIR && docker compose up -d"
}

# ----- AUTH: Autenticazione Apple per un endpoint -----
cmd_auth() {
    local num=$1

    if [ -z "$num" ]; then
        echo "Uso: $0 auth <numero_endpoint>"
        echo "  Es: $0 auth 5"
        exit 1
    fi

    local dir_name=$(get_ep_dir "$num")
    local data_dir="$BASE_DIR/$dir_name/data"
    local port=$(get_ep_port "$num")

    if [ ! -d "$data_dir" ]; then
        echo -e "${RED}Errore: $data_dir non esiste. Esegui prima: $0 add $num $num${NC}"
        exit 1
    fi

    print_header "Autenticazione Endpoint $num (porta $port)"

    echo -e "${YELLOW}Hai due opzioni per autenticare l'endpoint:${NC}"
    echo ""
    echo "  A) COPIARE auth.json da un endpoint gia' autenticato"
    echo "     (ogni endpoint DEVE usare un account Apple DIVERSO)"
    echo ""
    echo "  B) AUTENTICAZIONE INTERATTIVA via container temporaneo"
    echo ""
    read -p "Scegli [A/B]: " choice

    case "$choice" in
        [Aa])
            echo ""
            echo "Endpoint disponibili con auth.json:"
            for d in "$BASE_DIR"/endpoint*/data/auth.json; do
                if [ -f "$d" ]; then
                    local ep_dir=$(basename $(dirname $(dirname "$d")))
                    echo "  - $ep_dir/data/auth.json"
                fi
            done
            echo ""
            read -p "Da quale endpoint copiare? (es: endpoint2): " source_ep
            local source_auth="$BASE_DIR/$source_ep/data/auth.json"
            if [ ! -f "$source_auth" ]; then
                echo -e "${RED}File non trovato: $source_auth${NC}"
                exit 1
            fi
            cp "$source_auth" "$data_dir/auth.json"
            chown carrogwp:www-data "$data_dir/auth.json"
            echo -e "${YELLOW}ATTENZIONE: Hai copiato lo stesso account Apple!${NC}"
            echo -e "${YELLOW}Per prestazioni ottimali, ogni endpoint dovrebbe usare${NC}"
            echo -e "${YELLOW}un account Apple DIVERSO. Puoi ri-autenticare con: $0 auth $num${NC}"
            echo -e "${GREEN}auth.json copiato in $data_dir/${NC}"
            ;;
        [Bb])
            echo ""
            echo -e "${CYAN}Avvio container temporaneo per autenticazione...${NC}"
            echo -e "${YELLOW}Segui le istruzioni a schermo per inserire le credenziali Apple.${NC}"
            echo ""

            docker run --rm -it \
                --name "haystack-auth-ep${num}" \
                --network findmy-net \
                -v "$data_dir:/app/endpoint/data" \
                christld/macless-haystack \
                python /app/endpoint/register/register.py

            if [ -f "$data_dir/auth.json" ]; then
                chown carrogwp:www-data "$data_dir/auth.json"
                echo ""
                echo -e "${GREEN}Autenticazione completata! auth.json salvato in $data_dir/${NC}"
            else
                echo ""
                echo -e "${RED}auth.json non trovato. L'autenticazione potrebbe essere fallita.${NC}"
            fi
            ;;
        *)
            echo "Scelta non valida"
            exit 1
            ;;
    esac
}

# ----- STATUS: Mostra stato di tutti gli endpoint -----
cmd_status() {
    print_header "Stato Endpoint"

    printf "%-6s %-14s %-6s %-10s %-10s %-10s %s\n" \
        "EP" "Directory" "Porta" "Auth" "Container" "Health" "UUID Fix"
    printf "%s\n" "--------------------------------------------------------------------------------"

    for d in "$BASE_DIR"/endpoint*/; do
        [ ! -d "$d" ] && continue
        local dir_name=$(basename "$d")
        local num

        if [ "$dir_name" = "endpoint" ]; then
            num=1
        else
            num=$(echo "$dir_name" | sed 's/endpoint//')
        fi

        local port=$(get_ep_port "$num")
        local container_name="macless-haystack"
        [ "$num" -gt 1 ] && container_name="macless-haystack-${num}"

        # Auth
        local auth_status="${RED}NO${NC}"
        [ -f "$d/data/auth.json" ] && auth_status="${GREEN}OK${NC}"

        # Container
        local container_status="${RED}--${NC}"
        local running=$(docker ps --filter "name=^${container_name}$" --format "{{.Status}}" 2>/dev/null)
        if [ -n "$running" ]; then
            container_status="${GREEN}UP${NC}"
        else
            local exists=$(docker ps -a --filter "name=^${container_name}$" --format "{{.Status}}" 2>/dev/null)
            [ -n "$exists" ] && container_status="${YELLOW}STOP${NC}"
        fi

        # Health (curl)
        local health="${RED}--${NC}"
        if curl -sf "http://localhost:$port/" > /dev/null 2>&1; then
            health="${GREEN}OK${NC}"
        fi

        # UUID persistence
        local uuid_fix="${RED}NO${NC}"
        [ -f "$d/data/persistent_uuids.json" ] && uuid_fix="${GREEN}OK${NC}"

        printf "%-6s %-14s %-6s " "EP$num" "$dir_name" "$port"
        echo -e "$(printf '%-10b %-10b %-10b' "$auth_status" "$container_status" "$health") $(echo -e "$uuid_fix")"
    done

    echo ""

    # Anisette status
    local anisette_status="${RED}DOWN${NC}"
    if curl -sf "http://localhost:6969/" > /dev/null 2>&1; then
        anisette_status="${GREEN}UP${NC}"
    fi
    echo -e "Anisette Server (porta 6969): $anisette_status"

    # Daemon status
    local daemon_status=$(systemctl is-active "$SERVICE_NAME" 2>/dev/null || echo "not-found")
    case "$daemon_status" in
        active) echo -e "Rolling Keys Daemon: ${GREEN}ACTIVE${NC}" ;;
        inactive) echo -e "Rolling Keys Daemon: ${YELLOW}INACTIVE${NC}" ;;
        failed) echo -e "Rolling Keys Daemon: ${RED}FAILED${NC}" ;;
        *) echo -e "Rolling Keys Daemon: ${RED}$daemon_status${NC}" ;;
    esac
}

# ----- COMPOSE: Genera/aggiorna docker-compose.yml -----
cmd_compose() {
    local total=$1

    if [ -z "$total" ]; then
        echo "Uso: $0 compose <numero_totale_endpoint>"
        echo "  Es: $0 compose 8   (genera docker-compose per 8 endpoint)"
        exit 1
    fi

    print_header "Generazione docker-compose.yml per $total endpoint"

    local compose_file="$COMPOSE_DIR/docker-compose.yml"

    cat > "$compose_file" << 'HEADER'
# =============================================================
# Docker Compose - SganaTag FindMy Stack (auto-generato)
#
# Generato da: manage-endpoints.sh compose
# NON modificare manualmente - usa lo script per aggiornare.
# =============================================================

services:
  anisette-v3:
    image: dadoum/anisette-v3-server
    container_name: anisette-v3
    restart: unless-stopped
    ports:
      - "6969:6969"
    volumes:
      - anisette-v3_data:/home/Alcoholic/.config/anisette-v3
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:6969"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    networks:
      findmy-net:
        aliases:
          - anisette
HEADER

    for num in $(seq 1 "$total"); do
        local dir_name=$(get_ep_dir "$num")
        local port=$(get_ep_port "$num")
        local container_name="macless-haystack"
        [ "$num" -gt 1 ] && container_name="macless-haystack-${num}"
        local service_name="macless-haystack"
        [ "$num" -gt 1 ] && service_name="macless-haystack-${num}"

        cat >> "$compose_file" << EOF

  # === Endpoint $num (porta $port) ===
  ${service_name}:
    image: christld/macless-haystack
    container_name: ${container_name}
    restart: unless-stopped
    depends_on:
      anisette-v3:
        condition: service_healthy
    ports:
      - "${port}:6176"
    volumes:
      - /var/www/SganaTags/Apple-Project/${dir_name}/data:/app/endpoint/data
      - ./startup-endpoint.sh:/app/startup.sh:ro
    entrypoint: ["sh", "/app/startup.sh"]
    networks:
      - findmy-net
EOF
    done

    cat >> "$compose_file" << 'FOOTER'

volumes:
  anisette-v3_data:
    external: true

networks:
  findmy-net:
    driver: bridge
FOOTER

    echo -e "${GREEN}docker-compose.yml generato con $total endpoint${NC}"
    echo "File: $compose_file"
    echo ""
    echo "Per applicare: cd $COMPOSE_DIR && docker compose up -d"
}

# ----- UPDATE-DAEMON: Aggiorna il servizio systemd -----
cmd_update_daemon() {
    local total=$1

    if [ -z "$total" ]; then
        echo "Uso: $0 update-daemon <numero_totale_endpoint>"
        echo "  Es: $0 update-daemon 8"
        exit 1
    fi

    print_header "Aggiornamento servizio systemd per $total endpoint"

    if [ ! -f "$SERVICE_FILE" ]; then
        echo -e "${RED}Service file non trovato: $SERVICE_FILE${NC}"
        echo "Il servizio non e' installato su questo server."
        exit 1
    fi

    # Costruisci lista URL
    local urls=""
    for num in $(seq 1 "$total"); do
        local port=$(get_ep_port "$num")
        [ -n "$urls" ] && urls="${urls},"
        urls="${urls}http://localhost:${port}"
    done

    # Aggiorna ENDPOINT_URLS nel service file
    if grep -q "^Environment=\"ENDPOINT_URLS=" "$SERVICE_FILE"; then
        sed -i "s|^Environment=\"ENDPOINT_URLS=.*|Environment=\"ENDPOINT_URLS=$urls\"|" "$SERVICE_FILE"
    else
        sed -i "/^Environment=\"ENDPOINT_URL=/a Environment=\"ENDPOINT_URLS=$urls\"" "$SERVICE_FILE"
    fi

    # Aggiorna MAX_WORKERS
    if grep -q "^Environment=\"MAX_WORKERS=" "$SERVICE_FILE"; then
        sed -i "s|^Environment=\"MAX_WORKERS=.*|Environment=\"MAX_WORKERS=$total\"|" "$SERVICE_FILE"
    fi

    echo -e "${GREEN}Service file aggiornato:${NC}"
    echo "  ENDPOINT_URLS = $urls"
    echo "  MAX_WORKERS   = $total"
    echo ""

    # Reload e restart
    read -p "Vuoi ricaricare e riavviare il daemon ora? [y/N]: " confirm
    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        systemctl daemon-reload
        systemctl restart "$SERVICE_NAME"
        sleep 2
        systemctl status "$SERVICE_NAME" --no-pager -l | head -15
        echo -e "\n${GREEN}Daemon riavviato con $total endpoint.${NC}"
    else
        echo "Esegui manualmente:"
        echo "  sudo systemctl daemon-reload"
        echo "  sudo systemctl restart $SERVICE_NAME"
    fi
}

# ----- HELP -----
cmd_help() {
    cat << 'EOF'

  manage-endpoints.sh - Gestione endpoint macless-haystack

  COMANDI:
    add <da> <a>          Crea directory per nuovi endpoint
                          Es: ./manage-endpoints.sh add 5 8

    auth <N>              Autentica un endpoint (interattivo o copia)
                          Es: ./manage-endpoints.sh auth 5

    status                Mostra stato di tutti gli endpoint
                          Es: ./manage-endpoints.sh status

    compose <N>           Genera docker-compose.yml per N endpoint
                          Es: ./manage-endpoints.sh compose 8

    update-daemon <N>     Aggiorna il servizio systemd per N endpoint
                          Es: ./manage-endpoints.sh update-daemon 8

  WORKFLOW COMPLETO per aggiungere endpoint 5-8:

    1. ./manage-endpoints.sh add 5 8
    2. ./manage-endpoints.sh auth 5
    3. ./manage-endpoints.sh auth 6
    4. ./manage-endpoints.sh auth 7
    5. ./manage-endpoints.sh auth 8
    6. ./manage-endpoints.sh compose 8
    7. cd /var/www/SganaTags/Apple-Project/docker-findmy/
       docker compose up -d
    8. ./manage-endpoints.sh update-daemon 8
    9. ./manage-endpoints.sh status

EOF
}

# ----- MAIN -----
case "${1:-help}" in
    add)           cmd_add "$2" "$3" ;;
    auth)          cmd_auth "$2" ;;
    status)        cmd_status ;;
    compose)       cmd_compose "$2" ;;
    update-daemon) cmd_update_daemon "$2" ;;
    help|--help|-h) cmd_help ;;
    *)
        echo "Comando sconosciuto: $1"
        cmd_help
        exit 1
        ;;
esac
