#!/bin/bash
# MCP-ZERO Certificate Generator
# Creates TLS certificates for secure communication
# Implements offline-first resilience pattern

# Generate root CA certificate
generate_root_ca() {
  local certs_dir="$1"
  local ca_key="${certs_dir}/ca.key"
  local ca_cert="${certs_dir}/ca.crt"
  local subject="/C=US/ST=California/L=San Francisco/O=MCP-ZERO/OU=Security/CN=MCP-ZERO Root CA"
  
  echo "Generating root CA certificate..."
  
  # Generate CA private key
  openssl genrsa -out "${ca_key}" 4096
  
  # Generate CA certificate
  openssl req -x509 -new -nodes -key "${ca_key}" -sha256 -days 3650 \
    -out "${ca_cert}" -subj "${subject}"
  
  # Set proper permissions
  chmod 400 "${ca_key}"
  chmod 444 "${ca_cert}"
  
  echo "Root CA certificate generated successfully"
}

# Generate server certificate
generate_server_cert() {
  local certs_dir="$1"
  local ca_key="${certs_dir}/ca.key"
  local ca_cert="${certs_dir}/ca.crt"
  local server_key="${certs_dir}/server.key"
  local server_csr="${certs_dir}/server.csr"
  local server_cert="${certs_dir}/server.crt"
  local subject="/C=US/ST=California/L=San Francisco/O=MCP-ZERO/OU=Servers/CN=mcp-server"
  
  echo "Generating server certificate..."
  
  # Create config file for Subject Alternative Names
  cat > "${certs_dir}/server.cnf" << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]

[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
DNS.2 = mcp-api
DNS.3 = mcp-rpc
DNS.4 = mcp-dashboard
IP.1 = 127.0.0.1
EOF

  # Generate server private key
  openssl genrsa -out "${server_key}" 2048
  
  # Generate CSR with config
  openssl req -new -key "${server_key}" -out "${server_csr}" \
    -subj "${subject}" -config "${certs_dir}/server.cnf"
  
  # Generate certificate signed by our CA
  openssl x509 -req -in "${server_csr}" -CA "${ca_cert}" -CAkey "${ca_key}" \
    -CAcreateserial -out "${server_cert}" -days 1095 -sha256 \
    -extensions v3_req -extfile "${certs_dir}/server.cnf"
  
  # Clean up CSR
  rm "${server_csr}"
  
  # Set proper permissions
  chmod 400 "${server_key}"
  chmod 444 "${server_cert}"
  
  echo "Server certificate generated successfully"
}

# Generate client certificate
generate_client_cert() {
  local certs_dir="$1"
  local ca_key="${certs_dir}/ca.key"
  local ca_cert="${certs_dir}/ca.crt"
  local client_key="${certs_dir}/client.key"
  local client_csr="${certs_dir}/client.csr"
  local client_cert="${certs_dir}/client.crt"
  local subject="/C=US/ST=California/L=San Francisco/O=MCP-ZERO/OU=Clients/CN=mcp-client"
  
  echo "Generating client certificate..."
  
  # Create config file for client
  cat > "${certs_dir}/client.cnf" << EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]

[v3_req]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
EOF

  # Generate client private key
  openssl genrsa -out "${client_key}" 2048
  
  # Generate CSR with config
  openssl req -new -key "${client_key}" -out "${client_csr}" \
    -subj "${subject}" -config "${certs_dir}/client.cnf"
  
  # Generate certificate signed by our CA
  openssl x509 -req -in "${client_csr}" -CA "${ca_cert}" -CAkey "${ca_key}" \
    -CAcreateserial -out "${client_cert}" -days 1095 -sha256 \
    -extensions v3_req -extfile "${certs_dir}/client.cnf"
  
  # Clean up CSR
  rm "${client_csr}"
  
  # Set proper permissions
  chmod 400 "${client_key}"
  chmod 444 "${client_cert}"
  
  echo "Client certificate generated successfully"
}

# Generate JWT secret for authentication
generate_jwt_secret() {
  local certs_dir="$1"
  local jwt_secret="${certs_dir}/jwt_secret"
  
  echo "Generating JWT secret..."
  
  # Generate a random secret
  openssl rand -hex 32 > "${jwt_secret}"
  
  # Set proper permissions
  chmod 400 "${jwt_secret}"
  
  echo "JWT secret generated successfully"
}

# Create README with certificate information
create_cert_readme() {
  local certs_dir="$1"
  
  echo "Creating certificate README..."
  
  cat > "${certs_dir}/README.md" << EOF
# MCP-ZERO TLS Certificates

This directory contains TLS certificates for secure communication in the MCP-ZERO system.

## Files

- **ca.crt**: Root CA certificate (public)
- **ca.key**: Root CA private key (keep secure!)
- **server.crt**: Server certificate for API and RPC services
- **server.key**: Server private key (keep secure!)
- **client.crt**: Client certificate for authorized clients
- **client.key**: Client private key (keep secure!)
- **jwt_secret**: Secret key for JWT token generation (keep secure!)

## Security Notes

- Private key files (*.key and jwt_secret) should have 400 permissions (read-only by owner)
- Certificate files (*.crt) should have 444 permissions (read-only by everyone)
- Keep all private keys secure and never share them
- These certificates were generated during burn folder creation and are specific to this deployment

## Usage

To use these certificates with curl:

\`\`\`bash
curl --cacert ca.crt --cert client.crt --key client.key https://localhost:8081/api/v1/health
\`\`\`

## Regeneration

If you need to regenerate certificates:

\`\`\`bash
# From burn folder root directory
./scripts/cert_generator.sh regenerate
\`\`\`
EOF

  echo "Certificate README created successfully"
}

# Generate all certificates
generate_all_certs() {
  local certs_dir="$1"
  
  # Create directory
  mkdir -p "${certs_dir}"
  
  # Generate certificates
  generate_root_ca "${certs_dir}"
  generate_server_cert "${certs_dir}"
  generate_client_cert "${certs_dir}"
  generate_jwt_secret "${certs_dir}"
  
  # Create README
  create_cert_readme "${certs_dir}"
  
  echo "All certificates generated successfully"
}

# If script is executed directly, show usage
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  if [ "$1" == "regenerate" ] && [ -n "$2" ]; then
    # Regenerate certificates in specified directory
    generate_all_certs "$2"
  else
    echo "This script is intended to be sourced by burn.sh"
    echo "Usage: source $(basename "$0")"
    echo "Or: $(basename "$0") regenerate /path/to/certs/dir"
  fi
fi
