#!/bin/bash
# Copyright 2025 Carver Automation Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

CERT_DIR="/certs"
DAYS_VALID=3650

# Check if ALL certificates exist - including checker and other services
if [ -f "$CERT_DIR/root.pem" ] && [ -f "$CERT_DIR/core.pem" ] && [ -f "$CERT_DIR/proton.pem" ] && \
   [ -f "$CERT_DIR/nats.pem" ] && [ -f "$CERT_DIR/kv.pem" ] && [ -f "$CERT_DIR/sync.pem" ] && \
   [ -f "$CERT_DIR/otel.pem" ] && [ -f "$CERT_DIR/flowgger.pem" ] && [ -f "$CERT_DIR/trapd.pem" ] && \
   [ -f "$CERT_DIR/zen.pem" ] && [ -f "$CERT_DIR/db-event-writer.pem" ] && \
   [ -f "$CERT_DIR/snmp-checker.pem" ] && [ -f "$CERT_DIR/mapper.pem" ] && \
   [ -f "$CERT_DIR/rperf-client.pem" ] && [ -f "$CERT_DIR/agent.pem" ] && \
   [ -f "$CERT_DIR/poller.pem" ] && [ -f "$CERT_DIR/web.pem" ]; then
    echo "All certificates already exist, nothing to generate"
    exit 0
fi

echo "Generating missing mTLS certificates..."

# Create certificate directory
mkdir -p "$CERT_DIR"
cd "$CERT_DIR"

# Create serviceradar user and group if they don't exist (for consistency)
addgroup -S serviceradar 2>/dev/null || true
adduser -S -G serviceradar -s /bin/false -h /nonexistent serviceradar 2>/dev/null || true

# Generate Root CA only if it doesn't exist
if [ ! -f "$CERT_DIR/root.pem" ]; then
    echo "Generating Root CA..."
    openssl genrsa -out root-key.pem 4096
    openssl req -new -x509 -sha256 -key root-key.pem -out root.pem \
        -days $DAYS_VALID -subj "/C=US/ST=CA/L=San Francisco/O=ServiceRadar/OU=Docker/CN=ServiceRadar Root CA"
    
    # Set standard permissions for Root CA (readable by all)
    chmod 644 root.pem root-key.pem
    echo "Root CA generated successfully!"
else
    echo "Root CA already exists, skipping"
fi

# Function to generate certificate
generate_cert() {
    local component=$1
    local cn=$2
    local san=$3
    
    # Skip if certificate already exists
    if [ -f "$component.pem" ]; then
        echo "Certificate for $component already exists, skipping"
        return
    fi
    
    echo "Generating certificate for $component..."
    
    # Generate private key
    openssl genrsa -out "$component-key.pem" 2048
    
    # Create config with SAN
    cat > "$component.conf" <<EOF
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C = US
ST = CA
L = San Francisco
O = ServiceRadar
OU = Docker
CN = $cn

[v3_req]
keyUsage = keyEncipherment, dataEncipherment, digitalSignature
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = $san
EOF
    
    # Generate CSR
    openssl req -new -sha256 -key "$component-key.pem" \
        -out "$component.csr" -config "$component.conf"
    
    # Sign certificate
    openssl x509 -req -in "$component.csr" -CA root.pem \
        -CAkey root-key.pem -CAcreateserial -out "$component.pem" \
        -days $DAYS_VALID -sha256 -extensions v3_req -extfile "$component.conf"
    
    # Clean up
    rm "$component.csr" "$component.conf"
    
    # Set standard permissions (readable by all)
    chmod 644 "$component.pem" "$component-key.pem"
}

# Generate certificates for components (using NATS-compatible Common Names)
generate_cert "core" "core.serviceradar" "DNS:core,DNS:serviceradar-core,DNS:localhost,IP:127.0.0.1,IP:172.28.0.3"
generate_cert "proton" "proton.serviceradar" "DNS:proton,DNS:serviceradar-proton,DNS:localhost,IP:127.0.0.1,IP:172.28.0.2"
generate_cert "nats" "nats.serviceradar" "DNS:nats,DNS:serviceradar-nats,DNS:localhost,IP:127.0.0.1,IP:172.28.0.4"
generate_cert "kv" "kv.serviceradar" "DNS:kv,DNS:serviceradar-kv,DNS:localhost,IP:127.0.0.1,IP:172.28.0.5"
generate_cert "sync" "sync.serviceradar" "DNS:sync,DNS:serviceradar-sync,DNS:localhost,IP:127.0.0.1,IP:172.28.0.6"
generate_cert "otel" "otel.serviceradar" "DNS:otel,DNS:serviceradar-otel,DNS:localhost,IP:127.0.0.1,IP:172.28.0.7"
generate_cert "flowgger" "flowgger.serviceradar" "DNS:flowgger,DNS:serviceradar-flowgger,DNS:localhost,IP:127.0.0.1,IP:172.28.0.8"
generate_cert "trapd" "trapd.serviceradar" "DNS:trapd,DNS:serviceradar-trapd,DNS:localhost,IP:127.0.0.1,IP:172.28.0.9"
generate_cert "zen" "zen.serviceradar" "DNS:zen,DNS:serviceradar-zen,DNS:localhost,IP:127.0.0.1,IP:172.28.0.10"
generate_cert "db-event-writer" "db-event-writer.serviceradar" "DNS:db-event-writer,DNS:serviceradar-db-event-writer,DNS:localhost,IP:127.0.0.1,IP:172.28.0.11"

# Generate certificates for checker services
generate_cert "snmp-checker" "snmp-checker.serviceradar" "DNS:snmp-checker,DNS:serviceradar-snmp-checker,DNS:localhost,IP:127.0.0.1"
generate_cert "mapper" "mapper.serviceradar" "DNS:mapper,DNS:serviceradar-mapper,DNS:localhost,IP:127.0.0.1"
generate_cert "rperf-client" "rperf-client.serviceradar" "DNS:rperf-client,DNS:serviceradar-rperf-client,DNS:localhost,IP:127.0.0.1"

# Generate certificates for other services that might need them
generate_cert "agent" "agent.serviceradar" "DNS:agent,DNS:serviceradar-agent,DNS:localhost,IP:127.0.0.1"
generate_cert "poller" "poller.serviceradar" "DNS:poller,DNS:serviceradar-poller,DNS:localhost,IP:127.0.0.1"
generate_cert "web" "web.serviceradar" "DNS:web,DNS:serviceradar-web,DNS:localhost,IP:127.0.0.1"

# Copy core certificate for Proton to use
cp core.pem proton-core.pem
cp core-key.pem proton-core-key.pem

# Set standard permissions on copied certificates
chmod 644 proton-core.pem proton-core-key.pem

echo "Certificates generated successfully!"
ls -la *.pem