# Custom log format to show which location matched
log_format debug_log '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                     'location="$location_name"';

server {
    listen 80;
    server_name localhost;

    # Allow large client request bodies for file uploads in commits
    client_max_body_size 100G;

    # Root directory for the built Vue.js application
    root /usr/share/nginx/html;
    index index.html;

    # Default location name
    set $location_name "unknown";

    # Use custom log format for debugging
    access_log /var/log/nginx/access.log debug_log;

    # =================================================================
    # API PROXY RULES
    #
    # These specific locations are evaluated BEFORE the general SPA rule.
    # The order of these proxy rules matters - most specific first.
    # =================================================================

    # 1. API endpoints (all routes under /api/)
    # Covers: /api/auth/*, /api/repos/*, /api/models/*, /api/datasets/*,
    #         /api/spaces/*, /api/users/*, /api/organizations/*, /api/whoami-v2, etc.
    location /api/ {
        set $location_name "api";
        proxy_pass http://hub-api:48888;
        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;
    }

    # 2. Admin API endpoints (mounted at /admin/api/)
    # Covers: /admin/api/users/*, /admin/api/quota/*, /admin/api/stats
    location /admin/api/ {
        set $location_name "admin_api";
        proxy_pass http://hub-api:48888;
        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;
    }

    # 3. Organization API endpoints (mounted at /org/)
    # Covers: /org/create, /org/{name}, /org/{name}/members, /org/users/{username}/orgs
    location /org/ {
        set $location_name "org_api";
        proxy_pass http://hub-api:48888;
        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;
    }

    # 4. Git HTTP Smart Protocol endpoints
    # Covers: /{namespace}/{name}.git/info/refs, /{namespace}/{name}.git/git-upload-pack, etc.
    # This enables native Git clone/push operations
    # Pattern matches: /anything/anything.git/endpoint (hyphens, numbers, letters all OK)
    location ~ \.git/(info/refs|git-upload-pack|git-receive-pack|HEAD) {
        set $location_name "git_http";
        proxy_pass http://hub-api:48888;
        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;

        # Disable buffering for streaming Git protocol
        proxy_buffering off;
        proxy_request_buffering off;

        # Pass through authentication
        proxy_set_header Authorization $http_authorization;
        proxy_pass_header Authorization;

        # Git protocol specific headers
        proxy_set_header Content-Type $content_type;

        # Cloudflare compatibility - prevent caching and compression
        # Add these headers to tell Cloudflare not to cache Git protocol responses
        add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Accel-Buffering "no" always;

        # Ensure proper content type is preserved
        proxy_hide_header X-Content-Type-Options;
        proxy_hide_header Cache-Control;
    }

    # 5. Git LFS endpoints
    # Covers: /{type}s/{namespace}/{name}.git/info/lfs/* and /{namespace}/{name}.git/info/lfs/*
    location ~ \.git/info/lfs/ {
        set $location_name "git_lfs";
        proxy_pass http://hub-api:48888;
        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;
        # Important for large file uploads
        proxy_request_buffering off;
        client_body_buffer_size 128k;
    }

    # 6. Public file resolution routes (no /api prefix)
    # These are public-facing download endpoints
    # Pattern: /{type}s/{namespace}/{name}/resolve/{revision}/{path}
    location ~ ^/(models|datasets|spaces)/[^/]+/[^/]+/resolve/ {
        set $location_name "public_resolve_typed";
        proxy_pass http://hub-api:48888;
        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;
    }

    # 7. Legacy public file resolution route (no /api prefix, no type prefix)
    # Pattern: /{namespace}/{name}/resolve/{revision}/{path}
    # Must come AFTER the specific routes to avoid catching frontend routes
    location ~ ^/[^/]+/[^/]+/resolve/ {
        set $location_name "public_resolve_legacy";
        proxy_pass http://hub-api:48888;
        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;
    }


    # =================================================================
    # ADMIN FRONTEND SPA
    #
    # Serve admin portal at /admin (before main SPA fallback)
    # =================================================================
    location /admin {
        set $location_name "admin_spa";
        alias /usr/share/nginx/html-admin/;
        try_files $uri $uri/ /admin/index.html;
    }

    # =================================================================
    # MAIN FRONTEND SINGLE PAGE APP (SPA)
    #
    # This is the final fallback. If no API rule above matched,
    # Nginx assumes it's a frontend route and serves the main SPA.
    # =================================================================
    location / {
        set $location_name "main_spa";
        try_files $uri $uri/ /index.html;
    }
}
