# ============================================================================
# Nginx API Gateway Configuration
# Complete API gateway with rate limiting, CORS, authentication, and versioning
# Perfect for: REST APIs, GraphQL, microservices architecture
# Standards: 2025 Best Practices
# ============================================================================

# ============================================================================
# Rate Limiting Zones (Different limits for different API tiers)
# Place in http block of /etc/nginx/nginx.conf if not already present
# ============================================================================

# General API rate limit (by IP)
limit_req_zone $binary_remote_addr zone=api_general:10m rate=10r/s;

# Strict limit for authentication endpoints
limit_req_zone $binary_remote_addr zone=api_auth:10m rate=5r/s;

# Premium tier (identified by API key)
limit_req_zone $http_x_api_key zone=api_premium:10m rate=100r/s;

# Connection limits
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn_zone $http_x_api_key zone=api_key_conn:10m;

# ============================================================================
# API Key Validation Map
# Place in http block - Define valid API keys
# ============================================================================

# Map to validate API keys (use external key validation in production)
map $http_x_api_key $api_key_valid {
    default 0;
    # CUSTOMIZE: Add your API keys or use backend validation
    # "your-api-key-here" 1;
    # "another-api-key" 1;
}

# Map API key to rate limit tier
map $http_x_api_key $rate_limit_tier {
    default "free";
    # "premium-api-key-1" "premium";
    # "premium-api-key-2" "premium";
}

# ============================================================================
# HTTP to HTTPS Redirect
# ============================================================================

server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;

    # Let's Encrypt challenge
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # Redirect all HTTP to HTTPS
    location / {
        return 301 https://$server_name$request_uri;
    }
}

# ============================================================================
# HTTPS API Gateway Server Block
# ============================================================================

server {
    # Listen on port 443 with HTTP/2 support
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # Server name
    server_name api.example.com;

    # ========================================================================
    # SSL/TLS Configuration (2025 Standards)
    # ========================================================================

    # Certificate paths - CUSTOMIZE THESE
    ssl_certificate /etc/ssl/certs/api.example.com.crt;
    ssl_certificate_key /etc/ssl/private/api.example.com.key;

    # Modern protocols only
    ssl_protocols TLSv1.2 TLSv1.3;

    # Session settings
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    # Let client choose cipher
    ssl_prefer_server_ciphers off;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # ========================================================================
    # Security Headers (API-Specific)
    # ========================================================================

    # Hide Nginx version
    server_tokens off;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Prevent clickjacking (less relevant for APIs but good practice)
    add_header X-Frame-Options "DENY" always;

    # Prevent MIME sniffing
    add_header X-Content-Type-Options "nosniff" always;

    # XSS protection
    add_header X-XSS-Protection "1; mode=block" always;

    # Referrer Policy
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Content Security Policy (strict for API)
    add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'none';" always;

    # ========================================================================
    # Performance Optimizations
    # ========================================================================

    # Gzip compression for JSON responses
    gzip on;
    gzip_vary on;
    gzip_min_length 256;
    gzip_comp_level 6;
    gzip_types application/json application/javascript text/plain text/css application/xml;
    gzip_disable "msie6";

    # Client settings
    client_body_buffer_size 128k;
    client_max_body_size 5m;  # Adjust based on your API needs
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;

    # Timeouts
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 65;
    send_timeout 10;

    # ========================================================================
    # Logging (API-Specific with Request/Response Details)
    # ========================================================================

    # API log format with additional details
    log_format api_detailed '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" '
                           'api_key=$http_x_api_key '
                           'request_id=$request_id '
                           'request_time=$request_time '
                           'upstream_response_time=$upstream_response_time '
                           'upstream_addr=$upstream_addr '
                           'upstream_status=$upstream_status';

    access_log /var/log/nginx/api.example.com.access.log api_detailed;
    error_log /var/log/nginx/api.example.com.error.log warn;

    # ========================================================================
    # CORS Configuration (Preflight and Regular Requests)
    # ========================================================================

    # Set CORS headers for all responses
    set $cors_origin "";
    set $cors_methods "GET, POST, PUT, DELETE, OPTIONS, PATCH";
    set $cors_headers "Authorization, Content-Type, X-API-Key, X-Requested-With";

    # Allow specific origins (CUSTOMIZE THIS)
    if ($http_origin ~* (https?://(www\.)?example\.com|https?://app\.example\.com)) {
        set $cors_origin $http_origin;
    }

    # ========================================================================
    # API Documentation (Optional - OpenAPI/Swagger)
    # ========================================================================

    location /docs {
        # Serve API documentation
        alias /var/www/api-docs;
        index index.html;
        try_files $uri $uri/ =404;

        # No rate limiting for docs
        # Cache documentation
        expires 1h;
    }

    location /swagger.json {
        alias /var/www/api-docs/swagger.json;
        add_header Content-Type application/json;
        expires 1h;
    }

    # ========================================================================
    # Health Check Endpoints
    # ========================================================================

    location /health {
        access_log off;
        return 200 '{"status":"healthy","service":"api-gateway"}\n';
        add_header Content-Type application/json;
    }

    location /health/backend {
        access_log off;
        proxy_pass http://api_backend/health;
        proxy_connect_timeout 5s;
        proxy_read_timeout 5s;
    }

    # ========================================================================
    # Authentication Endpoints (Strict Rate Limiting)
    # ========================================================================

    location ~ ^/api/v[0-9]+/auth/ {
        # Strict rate limiting for auth endpoints
        limit_req zone=api_auth burst=10 nodelay;
        limit_conn addr 5;

        # CORS for auth endpoints
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
            add_header 'Access-Control-Allow-Methods' '$cors_methods' always;
            add_header 'Access-Control-Allow-Headers' '$cors_headers' always;
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;

        # Proxy to backend
        proxy_pass http://api_backend;
        include /etc/nginx/proxy_params;  # Standard proxy settings

        # Don't cache authentication responses
        add_header Cache-Control "no-store, no-cache, must-revalidate";
        add_header Pragma "no-cache";
    }

    # ========================================================================
    # API Version 1 Routes
    # ========================================================================

    location ~ ^/api/v1/ {
        # Rate limiting based on IP
        limit_req zone=api_general burst=20 nodelay;
        limit_conn addr 10;

        # CORS preflight
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
            add_header 'Access-Control-Allow-Methods' '$cors_methods' always;
            add_header 'Access-Control-Allow-Headers' '$cors_headers' always;
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        # CORS for actual requests
        add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length, X-Request-ID' always;

        # API Key validation (optional - uncomment if using)
        # if ($api_key_valid = 0) {
        #     return 401 '{"error":"Invalid API key"}\n';
        # }

        # Add request ID for tracing
        add_header X-Request-ID $request_id always;

        # Proxy to backend - CUSTOMIZE THIS
        proxy_pass http://api_backend_v1;

        # Essential proxy headers
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Request-ID $request_id;

        # Pass API key to backend
        proxy_set_header X-API-Key $http_x_api_key;

        # Connection header for keepalive
        proxy_set_header Connection "";

        # Timeouts (tune based on your API)
        proxy_connect_timeout 30s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffering
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;

        # Error handling
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_next_upstream_tries 2;

        # Don't cache API responses by default
        proxy_cache_bypass $http_authorization $http_x_api_key;
        add_header Cache-Control "no-cache, no-store, must-revalidate" always;
    }

    # ========================================================================
    # API Version 2 Routes (Example - newer version)
    # ========================================================================

    location ~ ^/api/v2/ {
        # Same rate limiting and CORS as v1
        limit_req zone=api_general burst=20 nodelay;
        limit_conn addr 10;

        # CORS preflight
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
            add_header 'Access-Control-Allow-Methods' '$cors_methods' always;
            add_header 'Access-Control-Allow-Headers' '$cors_headers' always;
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'X-Request-ID' $request_id always;

        # Proxy to v2 backend - CUSTOMIZE THIS
        proxy_pass http://api_backend_v2;

        # Include standard proxy settings
        include /etc/nginx/proxy_params;
    }

    # ========================================================================
    # GraphQL Endpoint (Optional)
    # ========================================================================

    location /graphql {
        # GraphQL typically uses POST only
        limit_methods POST OPTIONS;

        # Rate limiting
        limit_req zone=api_general burst=20 nodelay;
        limit_conn addr 10;

        # CORS
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
            add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' '$cors_headers' always;
            add_header 'Access-Control-Max-Age' 1728000;
            return 204;
        }

        add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;

        # Proxy to GraphQL backend
        proxy_pass http://graphql_backend;
        include /etc/nginx/proxy_params;

        # Increase timeout for complex queries
        proxy_read_timeout 120s;
    }

    # ========================================================================
    # WebSocket Support (for real-time APIs)
    # ========================================================================

    location /ws {
        # WebSocket rate limiting
        limit_req zone=api_general burst=10 nodelay;

        # Proxy to WebSocket backend
        proxy_pass http://websocket_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # WebSocket timeouts (longer)
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }

    # ========================================================================
    # API Rate Limit Status Endpoint
    # ========================================================================

    location /api/rate-limit-status {
        access_log off;
        return 200 '{"limit":"10 req/s","burst":20,"tier":"free"}\n';
        add_header Content-Type application/json;
    }

    # ========================================================================
    # Deny All Other Requests
    # ========================================================================

    location / {
        return 404 '{"error":"Endpoint not found","docs":"/docs"}\n';
        add_header Content-Type application/json;
    }
}

# ============================================================================
# Upstream Definitions (Backend Services)
# ============================================================================

# Main API backend (v1)
upstream api_backend_v1 {
    least_conn;
    server backend1.example.com:8080 max_fails=3 fail_timeout=30s;
    server backend2.example.com:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# API backend v2
upstream api_backend_v2 {
    least_conn;
    server backend-v2-1.example.com:8080 max_fails=3 fail_timeout=30s;
    server backend-v2-2.example.com:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# General backend (if not using versioned routes)
upstream api_backend {
    least_conn;
    server backend.example.com:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

# GraphQL backend (if applicable)
upstream graphql_backend {
    server graphql.example.com:4000;
    keepalive 16;
}

# WebSocket backend (if applicable)
upstream websocket_backend {
    server ws.example.com:8080;
    keepalive 16;
}

# ============================================================================
# Proxy Parameters File
# Create /etc/nginx/proxy_params with these standard settings:
# ============================================================================
# proxy_http_version 1.1;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Request-ID $request_id;
# proxy_set_header Connection "";
# proxy_connect_timeout 30s;
# proxy_send_timeout 60s;
# proxy_read_timeout 60s;
# proxy_buffering on;
# proxy_redirect off;

# ============================================================================
# Deployment Instructions
# ============================================================================
# 1. Customize:
#    - server_name (line 70)
#    - ssl_certificate paths (lines 78-79)
#    - CORS origins (line 167)
#    - upstream backend servers (lines 398-433)
#    - API key validation (lines 37-49 if using)
#
# 2. Create proxy params file:
#    sudo nano /etc/nginx/proxy_params
#    # Add content from lines 437-448
#
# 3. Test configuration:
#    sudo nginx -t
#
# 4. Deploy:
#    sudo cp api-gateway.conf /etc/nginx/sites-available/api.example.com.conf
#    sudo ln -s /etc/nginx/sites-available/api.example.com.conf /etc/nginx/sites-enabled/
#    sudo systemctl reload nginx
#
# 5. Test API:
#    # Basic request
#    curl -i https://api.example.com/api/v1/users
#
#    # With API key
#    curl -i -H "X-API-Key: your-key" https://api.example.com/api/v1/users
#
#    # Test CORS
#    curl -i -H "Origin: https://example.com" \
#         -X OPTIONS https://api.example.com/api/v1/users
#
# ============================================================================
# API Gateway Features Summary
# ============================================================================
# - Multi-version API support (/api/v1, /api/v2)
# - CORS configuration with origin whitelisting
# - Rate limiting (IP-based and API key-based)
# - API key validation (basic - extend for production)
# - Request ID tracking
# - WebSocket support
# - GraphQL support
# - Health check endpoints
# - Comprehensive logging
# - Security headers
# - Load balancing across backends
# ============================================================================
