#!/bin/bash
#
# Production Secrets Setup Script
# Purpose: Initialize and manage production secrets with Ansible Vault
#
# Usage:
#   ./scripts/setup-production-secrets.sh init       # Initialize new vault
#   ./scripts/setup-production-secrets.sh deploy     # Deploy secrets to production
#   ./scripts/setup-production-secrets.sh rotate     # Rotate secrets
#   ./scripts/setup-production-secrets.sh verify     # Verify secrets on server
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
ANSIBLE_DIR="${PROJECT_ROOT}/deployment/ansible"
VAULT_FILE="${ANSIBLE_DIR}/secrets/production-vault.yml"
INVENTORY="${ANSIBLE_DIR}/inventory/production.yml"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Logging functions
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Check prerequisites
check_prerequisites() {
    log_info "Checking prerequisites..."

    if ! command -v ansible-vault &> /dev/null; then
        log_error "ansible-vault not found. Please install Ansible."
        exit 1
    fi

    if ! command -v openssl &> /dev/null; then
        log_error "openssl not found. Please install OpenSSL."
        exit 1
    fi

    log_info "Prerequisites OK"
}

# Generate secure random password
generate_password() {
    local length="${1:-32}"
    openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length"
}

# Generate base64 encoded app key
generate_app_key() {
    openssl rand -base64 32
}

# Initialize vault with secure defaults
init_vault() {
    log_info "Initializing production secrets vault..."

    if [[ -f "$VAULT_FILE" ]]; then
        log_warn "Vault file already exists: $VAULT_FILE"
        read -p "Do you want to overwrite it? (yes/no): " -r
        if [[ ! $REPLY =~ ^[Yy]es$ ]]; then
            log_info "Aborting initialization"
            exit 0
        fi
    fi

    # Generate secure secrets
    log_info "Generating secure secrets..."
    DB_PASSWORD=$(generate_password 32)
    REDIS_PASSWORD=$(generate_password 32)
    APP_KEY=$(generate_app_key)
    JWT_SECRET=$(generate_password 64)
    REGISTRY_PASSWORD=$(generate_password 24)

    # Create vault file
    cat > "$VAULT_FILE" <<EOF
---
# Production Secrets Vault
# Generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC")

# Database Credentials
vault_db_name: framework_production
vault_db_user: framework_app
vault_db_password: ${DB_PASSWORD}

# Redis Credentials
vault_redis_password: ${REDIS_PASSWORD}

# Application Secrets
vault_app_key: ${APP_KEY}
vault_jwt_secret: ${JWT_SECRET}

# Docker Registry Credentials
vault_registry_url: git.michaelschiemer.de:5000
vault_registry_user: deploy
vault_registry_password: ${REGISTRY_PASSWORD}

# Security Configuration
vault_admin_allowed_ips: "127.0.0.1,::1,94.16.110.151"

# SMTP Configuration (update these manually)
vault_smtp_host: smtp.example.com
vault_smtp_port: 587
vault_smtp_user: noreply@michaelschiemer.de
vault_smtp_password: CHANGE_ME_SMTP_PASSWORD_HERE
EOF

    log_info "Vault file created with generated secrets"
    log_warn "IMPORTANT: Update SMTP credentials manually if needed"

    # Encrypt vault
    log_info "Encrypting vault file..."
    ansible-vault encrypt "$VAULT_FILE"

    log_info "✅ Vault initialized successfully"
    log_warn "Store the vault password securely (e.g., in password manager)"
}

# Deploy secrets to production
deploy_secrets() {
    log_info "Deploying secrets to production..."

    if [[ ! -f "$VAULT_FILE" ]]; then
        log_error "Vault file not found: $VAULT_FILE"
        log_error "Run './setup-production-secrets.sh init' first"
        exit 1
    fi

    cd "$ANSIBLE_DIR"

    log_info "Running Ansible playbook..."
    ansible-playbook \
        -i "$INVENTORY" \
        playbooks/setup-production-secrets.yml \
        --ask-vault-pass

    log_info "✅ Secrets deployed successfully"
}

# Rotate secrets (regenerate and redeploy)
rotate_secrets() {
    log_warn "⚠️  Secret rotation will:"
    log_warn "   1. Generate new passwords/keys"
    log_warn "   2. Update vault file"
    log_warn "   3. Deploy to production"
    log_warn "   4. Restart services"
    log_warn ""
    read -p "Continue with rotation? (yes/no): " -r

    if [[ ! $REPLY =~ ^[Yy]es$ ]]; then
        log_info "Rotation cancelled"
        exit 0
    fi

    # Backup current vault
    BACKUP_FILE="${VAULT_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
    log_info "Creating backup: $BACKUP_FILE"
    cp "$VAULT_FILE" "$BACKUP_FILE"

    # Decrypt vault
    log_info "Decrypting vault..."
    ansible-vault decrypt "$VAULT_FILE"

    # Generate new secrets
    log_info "Generating new secrets..."
    DB_PASSWORD=$(generate_password 32)
    REDIS_PASSWORD=$(generate_password 32)
    APP_KEY=$(generate_app_key)
    JWT_SECRET=$(generate_password 64)

    # Update vault file (keep registry password)
    sed -i "s/vault_db_password: .*/vault_db_password: ${DB_PASSWORD}/" "$VAULT_FILE"
    sed -i "s/vault_redis_password: .*/vault_redis_password: ${REDIS_PASSWORD}/" "$VAULT_FILE"
    sed -i "s/vault_app_key: .*/vault_app_key: ${APP_KEY}/" "$VAULT_FILE"
    sed -i "s/vault_jwt_secret: .*/vault_jwt_secret: ${JWT_SECRET}/" "$VAULT_FILE"

    # Re-encrypt vault
    log_info "Re-encrypting vault..."
    ansible-vault encrypt "$VAULT_FILE"

    log_info "✅ Secrets rotated"
    log_info "Backup saved to: $BACKUP_FILE"

    # Deploy rotated secrets
    deploy_secrets
}

# Verify secrets on server
verify_secrets() {
    log_info "Verifying secrets on production server..."

    cd "$ANSIBLE_DIR"

    ansible production_server \
        -i "$INVENTORY" \
        -m shell \
        -a "docker secret ls"

    log_info "Checking environment file..."
    ansible production_server \
        -i "$INVENTORY" \
        -m stat \
        -a "path=/home/deploy/secrets/.env.production"

    log_info "✅ Verification complete"
}

# Main command dispatcher
main() {
    check_prerequisites

    case "${1:-help}" in
        init)
            init_vault
            ;;
        deploy)
            deploy_secrets
            ;;
        rotate)
            rotate_secrets
            ;;
        verify)
            verify_secrets
            ;;
        help|*)
            cat <<EOF
Production Secrets Management

Usage: $0 <command>

Commands:
  init      Initialize new secrets vault with auto-generated secure values
  deploy    Deploy secrets from vault to production server
  rotate    Rotate secrets (generate new values and redeploy)
  verify    Verify secrets are properly deployed on server

Examples:
  $0 init       # First time setup
  $0 deploy     # Deploy after manual vault updates
  $0 rotate     # Monthly security rotation
  $0 verify     # Check deployment status

EOF
            ;;
    esac
}

main "$@"
