#!/usr/bin/env bash
# =============================================================================
# setup_custom_tls.sh - Configure custom TLS certificates for Caddy
# =============================================================================
# Updates caddy-addon/tls-snippet.conf to use corporate/internal certificates
# instead of Let's Encrypt.
#
# Usage:
#   bash scripts/setup_custom_tls.sh                    # Interactive mode
#   bash scripts/setup_custom_tls.sh cert.crt key.key   # Non-interactive mode
#   bash scripts/setup_custom_tls.sh --remove           # Reset to Let's Encrypt
#
# Prerequisites:
#   - Place certificate files in ./certs/ directory
#   - Certificate paths are relative to container (/etc/caddy/certs/)
# =============================================================================

set -euo pipefail

source "$(dirname "$0")/utils.sh" && init_paths

SNIPPET_FILE="$PROJECT_ROOT/caddy-addon/tls-snippet.conf"
SNIPPET_EXAMPLE="$PROJECT_ROOT/caddy-addon/tls-snippet.conf.example"
CERTS_DIR="$PROJECT_ROOT/certs"

# Legacy file that causes duplicate host errors (must be cleaned up on migration)
# TODO: Remove OLD_CONFIG and cleanup_legacy_config() after v3.0 release (all users migrated)
OLD_CONFIG="$PROJECT_ROOT/caddy-addon/custom-tls.conf"

# =============================================================================
# FUNCTIONS
# =============================================================================

cleanup_legacy_config() {
    # Remove old custom-tls.conf that causes duplicate host errors
    # This is needed for users upgrading from older versions
    if [[ -f "$OLD_CONFIG" ]]; then
        log_warning "Removing obsolete custom-tls.conf (causes duplicate host errors)"
        rm -f "$OLD_CONFIG"
    fi
}

show_help() {
    cat << EOF
Setup Custom TLS Certificates for Caddy

Usage: $(basename "$0") [OPTIONS] [CERT_FILE] [KEY_FILE]

Options:
  -h, --help     Show this help message
  --remove       Reset to Let's Encrypt automatic certificates

Arguments:
  CERT_FILE      Path to certificate file (relative to ./certs/)
  KEY_FILE       Path to private key file (relative to ./certs/)

Examples:
  $(basename "$0")                           # Interactive mode
  $(basename "$0") wildcard.crt wildcard.key # Use specific files
  $(basename "$0") --remove                  # Reset to Let's Encrypt

The script will:
1. Detect certificate files in ./certs/
2. Update caddy-addon/tls-snippet.conf with your certificate paths
3. Optionally restart Caddy

EOF
}

find_certificates() {
    # Find certificate files in certs directory
    local certs=()
    if [[ -d "$CERTS_DIR" ]]; then
        while IFS= read -r -d '' file; do
            certs+=("$(basename "$file")")
        done < <(find "$CERTS_DIR" -maxdepth 1 -type f \( -name "*.crt" -o -name "*.pem" -o -name "*.cer" \) -print0 2>/dev/null)
    fi
    echo "${certs[*]:-}"
}

find_keys() {
    # Find key files in certs directory
    local keys=()
    if [[ -d "$CERTS_DIR" ]]; then
        while IFS= read -r -d '' file; do
            keys+=("$(basename "$file")")
        done < <(find "$CERTS_DIR" -maxdepth 1 -type f \( -name "*.key" -o -name "*-key.pem" \) -print0 2>/dev/null)
    fi
    echo "${keys[*]:-}"
}

ensure_snippet_exists() {
    # Create tls-snippet.conf from example if it doesn't exist
    # This ensures the file survives git updates (it's gitignored)
    if [[ ! -f "$SNIPPET_FILE" ]]; then
        if [[ -f "$SNIPPET_EXAMPLE" ]]; then
            cp "$SNIPPET_EXAMPLE" "$SNIPPET_FILE"
            log_info "Created tls-snippet.conf from template"
        else
            # Fallback: create default content directly
            remove_config
        fi
    fi
}

generate_config() {
    local cert_file="$1"
    local key_file="$2"

    cat > "$SNIPPET_FILE" << EOF
# TLS Configuration Snippet
# Generated by setup_custom_tls.sh on $(date -Iseconds)
# Using custom certificates instead of Let's Encrypt.
# Reset to Let's Encrypt: make setup-tls --remove

(service_tls) {
    tls /etc/caddy/certs/$cert_file /etc/caddy/certs/$key_file
}
EOF

    log_success "Generated $SNIPPET_FILE"
}

remove_config() {
    cat > "$SNIPPET_FILE" << 'EOF'
# TLS Configuration Snippet
# Imported by all service blocks in the main Caddyfile.
#
# Default: Empty (uses Let's Encrypt automatic certificates)
# Custom: Overwritten by 'make setup-tls' with your certificate paths
# Reset: Run 'make setup-tls --remove' to restore Let's Encrypt

(service_tls) {
    # Default: Let's Encrypt automatic certificates (empty = no override)
}
EOF

    log_success "Reset to Let's Encrypt (automatic certificates)"
}

restart_caddy() {
    if wt_yesno "Restart Caddy" "Do you want to restart Caddy to apply the new configuration?" "yes"; then
        log_info "Restarting Caddy..."
        docker compose -p localai restart caddy
        log_success "Caddy restarted"
    else
        log_info "Skipped Caddy restart. Run manually: docker compose -p localai restart caddy"
    fi
}

# =============================================================================
# MAIN
# =============================================================================

main() {
    # Handle arguments
    case "${1:-}" in
        -h|--help)
            show_help
            exit 0
            ;;
        --remove)
            cleanup_legacy_config
            remove_config
            restart_caddy
            exit 0
            ;;
    esac

    # Clean up legacy config that causes duplicate hosts
    cleanup_legacy_config

    # Ensure snippet file exists (survives git updates)
    ensure_snippet_exists

    # Ensure certs directory exists
    mkdir -p "$CERTS_DIR"

    local cert_file=""
    local key_file=""

    # Non-interactive mode
    if [[ $# -ge 2 ]]; then
        cert_file="$1"
        key_file="$2"

        if [[ ! -f "$CERTS_DIR/$cert_file" ]]; then
            log_error "Certificate not found: $CERTS_DIR/$cert_file"
            exit 1
        fi
        if [[ ! -f "$CERTS_DIR/$key_file" ]]; then
            log_error "Key not found: $CERTS_DIR/$key_file"
            exit 1
        fi
    else
        # Interactive mode
        require_whiptail

        # Find available certificates
        local certs_arr
        IFS=' ' read -ra certs_arr <<< "$(find_certificates)"

        if [[ ${#certs_arr[@]} -eq 0 ]]; then
            wt_msg "No Certificates Found" "No certificate files found in ./certs/\n\nPlease place your certificate (.crt, .pem, .cer) and key (.key) files in the certs/ directory first."
            exit 1
        fi

        # Build menu items for certificates
        local cert_items=()
        for cert in "${certs_arr[@]}"; do
            cert_items+=("$cert" "")
        done

        cert_file=$(wt_menu "Select Certificate" "Choose your TLS certificate file:" "${cert_items[@]}")
        [[ -z "$cert_file" ]] && exit 1

        # Find available keys
        local keys_arr
        IFS=' ' read -ra keys_arr <<< "$(find_keys)"

        if [[ ${#keys_arr[@]} -eq 0 ]]; then
            wt_msg "No Keys Found" "No key files found in ./certs/\n\nPlease place your private key (.key) file in the certs/ directory."
            exit 1
        fi

        # Build menu items for keys
        local key_items=()
        for key in "${keys_arr[@]}"; do
            key_items+=("$key" "")
        done

        key_file=$(wt_menu "Select Private Key" "Choose your TLS private key file:" "${key_items[@]}")
        [[ -z "$key_file" ]] && exit 1
    fi

    log_info "Using certificate: $cert_file"
    log_info "Using key: $key_file"

    # Ensure certificate files are readable by Caddy container
    # (Docker volume mounts preserve host permissions, Caddy may run as different UID)
    chmod 644 "$CERTS_DIR/$cert_file" "$CERTS_DIR/$key_file"

    # Generate configuration
    generate_config "$cert_file" "$key_file"

    echo ""
    log_info "Custom TLS configured successfully!"
    log_info "All services will use: /etc/caddy/certs/$cert_file"
    echo ""

    # Restart Caddy
    restart_caddy
}

main "$@"
