# Fogbreak.io — Production Nginx Configuration
# ================================================
#
# Location: /etc/nginx/sites-available/fogbreak.io (or similar)
# Enable with: ln -s /etc/nginx/sites-available/fogbreak.io /etc/nginx/sites-enabled/
# Test: sudo nginx -t
# Reload: sudo systemctl reload nginx
#
# Features:
# - HTTP → HTTPS redirect
# - SSL/TLS with HTTP/2
# - PHP-FPM via Unix socket
# - Static file caching (30d images, 7d CSS/JS)
# - Gzip compression
# - Security headers (X-Frame-Options, X-Content-Type-Options, etc.)
# - Rate limiting on API endpoints (60 req/min)
# - Blocks access to sensitive files (.git, config.php, .env)
# - Reverse proxy for Next.js frontend (instruction 15, currently commented)
# - Comprehensive logging

upstream php_fpm {
    server unix:/var/run/php/php8.2-fpm.sock;
}

# Rate limiting zone for API endpoints
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m;
limit_req_zone $binary_remote_addr zone=webhook_limit:10m rate=30r/m;

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name fogbreak.io www.fogbreak.io;

    # Allow certbot challenges
    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }

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

# Main HTTPS server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name fogbreak.io www.fogbreak.io;

    # SSL/TLS Configuration (Certbot auto-managed)
    ssl_certificate /etc/letsencrypt/live/fogbreak.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/fogbreak.io/privkey.pem;

    # SSL Security (A+ rating)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS (strict transport security)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

    # CSP (Content Security Policy) — adjust for your domain
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://apis.google.com;" always;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
    gzip_disable "msie6";

    # Logging
    access_log /var/log/fogbreak/access.log;
    error_log /var/log/fogbreak/error.log warn;

    # Application root
    root /var/www/fogbreak.io/app;
    index fogbreak.html index.html;

    # === STATIC FILES (HIGH CACHE) ===

    # Images: 30-day cache
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # CSS & JavaScript: 7-day cache
    location ~* \.(css|js)$ {
        expires 7d;
        add_header Cache-Control "public";
        types {
            text/css css;
            application/javascript js;
        }
    }

    # Fonts: 30-day cache
    location ~* \.(ttf|otf|eot|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # === API ENDPOINTS ===

    # Deployment webhook (lower rate limit: 30 req/min)
    location ~ ^/deploy/webhook\.php$ {
        limit_req zone=webhook_limit burst=5 nodelay;

        try_files $uri =404;
        fastcgi_pass php_fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        # Allow webhook payload
        client_max_body_size 10m;

        access_log /var/log/fogbreak/webhook.log;
    }

    # Cron runner (local-only access)
    location ~ ^/api/cron\.php$ {
        # Restrict to localhost only
        allow 127.0.0.1;
        allow ::1;
        deny all;

        try_files $uri =404;
        fastcgi_pass php_fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        access_log /var/log/fogbreak/cron.log;
    }

    # General API endpoints (rate limited: 60 req/min)
    location ~ ^/api/.*\.php$ {
        limit_req zone=api_limit burst=10 nodelay;

        try_files $uri =404;
        fastcgi_pass php_fpm;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        # Security: prevent script execution in upload dirs
        location ~ ^/api/(uploads|temp)/ {
            deny all;
        }
    }

    # === PROTECTED ENDPOINTS (BLOCK) ===

    # Block access to config files
    location ~ /config\.php {
        deny all;
        access_log off;
    }

    # Block access to .env files
    location ~ /\.env {
        deny all;
        access_log off;
    }

    # Block access to Git directory
    location ~ /\.git {
        deny all;
        access_log off;
    }

    # Block access to backup files
    location ~ \.(bak|old|sql|tar|gz)$ {
        deny all;
        access_log off;
    }

    # === NEXT.JS FRONTEND (Phase 2+ — Currently Disabled) ===
    #
    # Uncomment when Next.js frontend is deployed on localhost:3000
    # (See instruction 15-NEXTJS-WEB-APP.md)
    #
    # location /web/ {
    #     proxy_pass http://localhost:3000/web/;
    #     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;
    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #     proxy_set_header X-Forwarded-Proto $scheme;
    #     proxy_cache_bypass $http_upgrade;
    #     proxy_redirect off;
    # }

    # === REACT NATIVE API GATEWAY (Phase 2+ — Currently Disabled) ===
    #
    # Uncomment when mobile app API gateway is deployed
    #
    # location /mobile/api/ {
    #     proxy_pass http://localhost:3001/api/;
    #     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;
    # }

    # === PHP HANDLER ===
    # Catch-all for PHP files in app root
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass php_fpm;
        fastcgi_index index.html;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_param HTTP_PROXY "";
        fastcgi_param HTTPS on;

        include fastcgi_params;
    }

    # === HTML ROUTES ===
    # Main app entry points
    location ~ ^/(fogbreak|admin|portal|sign|index)\.html$ {
        try_files $uri $uri/ =404;
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }

    # Service Worker (no cache)
    location = /sw.js {
        types {
            application/javascript js;
        }
        expires -1;
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }

    # PWA Manifest (no cache)
    location = /manifest.json {
        types {
            application/manifest+json json;
        }
        expires -1;
        add_header Cache-Control "no-cache";
    }

    # === FALLBACK ===
    # Serve index.html for non-existent files (SPA routing)
    location / {
        try_files $uri $uri/ /index.html;
        expires 1h;
    }

    # === HEALTH CHECK ===
    location = /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }

}

# Additional security: limit connections
limit_conn_zone $binary_remote_addr zone=addr:10m;

# In http block (add to main nginx.conf if not present):
# limit_conn addr 10;
