#!/bin/bash
# =============================================================================
# Mailu Production Deployment Script
# =============================================================================
# This script automates the deployment of Mailu mail server for production.
# It handles:
#   1. CoreDNS configuration with DNS-over-TLS for DNSSEC validation
#   2. TLS certificate secret creation
#   3. Admin credentials secret creation
#   4. Mailu Helm deployment (admin user created automatically via initialAccount)
#
# Usage:
#   ./deploy-mailu-prod.sh [--domain DOMAIN] [--admin-password PASSWORD]
#
# Example:
#   ./deploy-mailu-prod.sh --domain bakewise.ai --admin-password 'SecurePass123!'
# =============================================================================

set -e

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

# Default values
DOMAIN="${DOMAIN:-bakewise.ai}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-}"
NAMESPACE="bakery-ia"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MAILU_HELM_DIR="$(dirname "$SCRIPT_DIR")"

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --domain)
            DOMAIN="$2"
            shift 2
            ;;
        --admin-password)
            ADMIN_PASSWORD="$2"
            shift 2
            ;;
        --help)
            echo "Usage: $0 [--domain DOMAIN] [--admin-password PASSWORD]"
            echo ""
            echo "Options:"
            echo "  --domain          Domain for Mailu (default: bakewise.ai)"
            echo "  --admin-password  Password for admin@DOMAIN user"
            echo ""
            exit 0
            ;;
        *)
            echo -e "${RED}Unknown option: $1${NC}"
            exit 1
            ;;
    esac
done

print_step() {
    echo -e "\n${BLUE}==>${NC} ${GREEN}$1${NC}"
}

print_warning() {
    echo -e "${YELLOW}WARNING:${NC} $1"
}

print_error() {
    echo -e "${RED}ERROR:${NC} $1"
}

print_success() {
    echo -e "${GREEN}✓${NC} $1"
}

# =============================================================================
# Step 0: Prerequisites Check
# =============================================================================
print_step "Step 0: Checking prerequisites..."

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

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

if ! kubectl get namespace "$NAMESPACE" &>/dev/null; then
    print_warning "Namespace $NAMESPACE does not exist. Creating..."
    kubectl create namespace "$NAMESPACE"
fi

print_success "Prerequisites check passed"

# =============================================================================
# Step 1: Configure CoreDNS with DNS-over-TLS for DNSSEC
# =============================================================================
print_step "Step 1: Configuring CoreDNS with DNS-over-TLS for DNSSEC validation..."

# Check if CoreDNS is already configured with DNS-over-TLS
CURRENT_FORWARD=$(kubectl get configmap coredns -n kube-system -o jsonpath='{.data.Corefile}' 2>/dev/null | grep -o 'tls://1.1.1.1' || echo "")

if [ -z "$CURRENT_FORWARD" ]; then
    echo "Updating CoreDNS to use DNS-over-TLS with Cloudflare for DNSSEC validation..."

    # Create a temporary file with the CoreDNS configuration
    TEMP_COREFILE=$(mktemp)
    cat > "$TEMP_COREFILE" <<EOF
.:53 {
    errors
    health {
       lameduck 5s
    }
    ready
    kubernetes cluster.local in-addr.arpa ip6.arpa {
       pods insecure
       fallthrough in-addr.arpa ip6.arpa
       ttl 30
    }
    prometheus :9153
    forward . tls://1.1.1.1 tls://1.0.0.1 {
       tls_servername cloudflare-dns.com
       health_check 5s
    }
    cache 30 {
       disable success cluster.local
       disable denial cluster.local
    }
    loop
    reload
    loadbalance
}
EOF

    # Apply the configuration
    kubectl patch configmap coredns -n kube-system --type merge -p "{
      \"data\": {
        \"Corefile\": \"$(cat "$TEMP_COREFILE" | sed 's/\\/\\\\/g' | sed ':a;N;$!ba;s/\n/\\\\n/g')\"
      }
    }"

    rm -f "$TEMP_COREFILE"

    # Restart CoreDNS
    kubectl rollout restart deployment coredns -n kube-system
    kubectl rollout status deployment coredns -n kube-system --timeout=60s

    print_success "CoreDNS configured with DNS-over-TLS for DNSSEC validation"
else
    print_success "CoreDNS already configured with DNS-over-TLS"
fi

# Get CoreDNS service IP for Mailu configuration
COREDNS_IP=$(kubectl get svc kube-dns -n kube-system -o jsonpath='{.spec.clusterIP}')
echo "CoreDNS service IP: $COREDNS_IP"

# =============================================================================
# Step 2: Create TLS Certificate Secret
# =============================================================================
print_step "Step 2: Creating TLS certificate secret..."

if kubectl get secret mailu-certificates -n "$NAMESPACE" &>/dev/null; then
    print_success "TLS certificate secret already exists"
else
    TEMP_DIR=$(mktemp -d)
    cd "$TEMP_DIR"

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
        -keyout tls.key -out tls.crt \
        -subj "/CN=mail.$DOMAIN/O=$DOMAIN" 2>/dev/null

    kubectl create secret tls mailu-certificates \
        --cert=tls.crt \
        --key=tls.key \
        -n "$NAMESPACE"

    rm -rf "$TEMP_DIR"
    print_success "TLS certificate secret created"
fi

# =============================================================================
# Step 3: Create Admin Credentials Secret
# =============================================================================
print_step "Step 3: Creating admin credentials secret..."

if kubectl get secret mailu-admin-credentials -n "$NAMESPACE" &>/dev/null; then
    print_success "Admin credentials secret already exists"
    # Retrieve existing password for summary output
    if [ -z "$ADMIN_PASSWORD" ]; then
        ADMIN_PASSWORD=$(kubectl get secret mailu-admin-credentials -n "$NAMESPACE" -o jsonpath='{.data.password}' | base64 -d)
    fi
else
    if [ -z "$ADMIN_PASSWORD" ]; then
        # Generate a random password
        ADMIN_PASSWORD=$(openssl rand -base64 16 | tr -d '/+=' | head -c 16)
        echo -e "${YELLOW}Generated admin password: $ADMIN_PASSWORD${NC}"
        echo -e "${YELLOW}Please save this password securely!${NC}"
    fi

    kubectl create secret generic mailu-admin-credentials \
        --from-literal=password="$ADMIN_PASSWORD" \
        -n "$NAMESPACE"

    print_success "Admin credentials secret created"
fi

# =============================================================================
# Step 4: Deploy Mailu via Helm
# =============================================================================
print_step "Step 4: Deploying Mailu via Helm..."

# Add Mailu Helm repository
helm repo add mailu https://mailu.github.io/helm-charts 2>/dev/null || true
helm repo update mailu

# Deploy Mailu with CoreDNS configuration
helm upgrade --install mailu mailu/mailu \
    -n "$NAMESPACE" \
    -f "$MAILU_HELM_DIR/values.yaml" \
    -f "$MAILU_HELM_DIR/prod/values.yaml" \
    --set global.custom_dns_servers="$COREDNS_IP" \
    --timeout 10m

print_success "Mailu Helm release deployed (admin user will be created automatically)"

# =============================================================================
# Step 5: Wait for Pods to be Ready
# =============================================================================
print_step "Step 5: Waiting for Mailu pods to be ready..."

echo "This may take 5-10 minutes (ClamAV takes time to initialize)..."

# Wait for admin pod first (it's the key dependency)
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=admin -n "$NAMESPACE" --timeout=300s || {
    print_error "Admin pod failed to start. Checking logs..."
    kubectl logs -n "$NAMESPACE" -l app.kubernetes.io/component=admin --tail=50
    exit 1
}

print_success "Admin pod is ready"

# Show pod status
echo ""
echo "Mailu Pod Status:"
kubectl get pods -n "$NAMESPACE" | grep mailu

print_success "Admin user created automatically via Helm initialAccount"

# =============================================================================
# Summary
# =============================================================================
echo ""
echo "=============================================="
echo -e "${GREEN}Mailu Deployment Complete!${NC}"
echo "=============================================="
echo ""
echo "Admin Credentials:"
echo "  Email:    admin@$DOMAIN"
echo "  Password: $ADMIN_PASSWORD"
echo ""
echo "Access URLs (configure Ingress/DNS first):"
echo "  Admin Panel: https://mail.$DOMAIN/admin"
echo "  Webmail:     https://mail.$DOMAIN/webmail"
echo "  SMTP:        mail.$DOMAIN:587 (STARTTLS)"
echo "  IMAP:        mail.$DOMAIN:993 (SSL)"
echo ""
echo "DNS Configuration:"
echo "  CoreDNS is configured with DNS-over-TLS (Cloudflare) for DNSSEC validation"
echo "  CoreDNS IP: $COREDNS_IP"
echo ""
echo "Next Steps:"
echo "  1. Configure MailerSend:"
echo "     - Sign up at https://accounts.mailersend.com/signup"
echo "     - Add domain '$DOMAIN' and verify DNS records"
echo "     - Generate SMTP credentials (Email -> Domains -> SMTP)"
echo "     - Update secret: kubectl edit secret mailu-mailersend-credentials -n $NAMESPACE"
echo ""
echo "  2. Configure DNS records in Cloudflare for '$DOMAIN':"
echo "     - A record: mail -> <your-server-IP>"
echo "     - MX record: @ -> mail.$DOMAIN (priority 10)"
echo "     - TXT (SPF): @ -> v=spf1 include:mailersend.net ~all"
echo "     - TXT (DKIM): mlsend._domainkey -> <from MailerSend dashboard>"
echo "     - TXT (DMARC): _dmarc -> v=DMARC1; p=quarantine; rua=mailto:admin@$DOMAIN"
echo ""
echo "  3. Get Mailu DKIM key (for direct sending):"
echo "     kubectl exec -n $NAMESPACE deployment/mailu-admin -- cat /dkim/$DOMAIN.dkim.pub"
echo ""
echo "  4. Configure Ingress for mail.$DOMAIN"
echo ""
echo "To check pod status:"
echo "  kubectl get pods -n $NAMESPACE | grep mailu"
echo ""
