<?xml version="1.0" encoding="UTF-8"?>
<!--
    ROA2WEB - IIS Web Configuration (Ultrathin Monolith Architecture)

    This configuration enables:
    - SPA routing for Vue.js (all routes fallback to index.html)
    - Reverse proxy for /api/* to UNIFIED backend FastAPI service (localhost:8000)
      ├── All modules proxied to single backend:
      │   ├── /api/reports/*     → Backend Reports module
      │   ├── /api/data-entry/*  → Backend Data Entry module
      │   └── /api/telegram/*    → Backend Telegram module
      └── Single Windows service: ROA2WEB-Backend (port 8000)
    - Compression and caching for optimal performance
    - Security headers

    Prerequisites:
    - IIS URL Rewrite Module: https://www.iis.net/downloads/microsoft/url-rewrite
    - IIS Application Request Routing (ARR): https://www.iis.net/downloads/microsoft/application-request-routing
-->
<configuration>
    <system.webServer>

        <!-- Static Content Compression -->
        <urlCompression doStaticCompression="true" doDynamicCompression="true" />

        <!-- Default Document -->
        <defaultDocument>
            <files>
                <clear />
                <add value="index.html" />
            </files>
        </defaultDocument>

        <!-- Static Content Settings -->
        <staticContent>
            <!-- Enable MIME types for modern web assets -->
            <!-- Remove first to avoid duplicates, then add -->
            <remove fileExtension=".json" />
            <mimeMap fileExtension=".json" mimeType="application/json" />
            <remove fileExtension=".woff" />
            <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
            <remove fileExtension=".woff2" />
            <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
            <remove fileExtension=".svg" />
            <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
            <remove fileExtension=".webmanifest" />
            <mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />

            <!-- No global client-side cache - outbound rules handle this per file type -->
            <clientCache cacheControlMode="NoControl" />
        </staticContent>

        <!-- Custom HTTP Headers (Security) -->
        <httpProtocol>
            <customHeaders>
                <!-- Security Headers -->
                <add name="X-Frame-Options" value="DENY" />
                <add name="X-Content-Type-Options" value="nosniff" />
                <add name="X-XSS-Protection" value="1; mode=block" />
                <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
                <add name="Permissions-Policy" value="geolocation=(), microphone=(), camera=()" />

                <!-- Content Security Policy (adjust as needed) -->
                <add name="Content-Security-Policy" value="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' ws: wss:" />

                <!-- Remove Server header for security -->
                <remove name="X-Powered-By" />
            </customHeaders>
        </httpProtocol>

        <!-- URL Rewrite Rules -->
        <rewrite>
            <rules>

                <!-- Rule 1: Force HTTPS (redirect HTTP to HTTPS) -->
                <rule name="Force HTTPS" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
                </rule>

                <!-- Rule 2: Reverse Proxy for API Requests -->
                <rule name="API Reverse Proxy" stopProcessing="true">
                    <match url="^api/(.*)" />
                    <action type="Rewrite" url="http://localhost:8000/api/{R:1}" />
                </rule>

                <!-- Rule 3: Health Check Endpoint -->
                <rule name="Health Check Proxy" stopProcessing="true">
                    <match url="^health$" />
                    <action type="Rewrite" url="http://localhost:8000/health" />
                </rule>

                <!-- Rule 4: Don't rewrite if file exists (static assets) -->
                <rule name="StaticContent" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" />
                    </conditions>
                    <action type="None" />
                </rule>

                <!-- Rule 5: Don't rewrite if directory exists -->
                <rule name="StaticDirectory" stopProcessing="true">
                    <match url=".*" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
                    </conditions>
                    <action type="None" />
                </rule>

                <!-- Rule 6: SPA Routing - Rewrite all other requests to index.html -->
                <rule name="SPA Fallback" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_URI}" pattern="^/api" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.html" />
                </rule>

            </rules>

            <!-- Outbound Rules for response headers -->
            <outboundRules>
                <!-- HSTS Header for HTTPS connections -->
                <rule name="Add HSTS Header" preCondition="IsHTTPS">
                    <match serverVariable="RESPONSE_Strict-Transport-Security" pattern=".*" />
                    <action type="Rewrite" value="max-age=31536000; includeSubDomains" />
                </rule>

                <!-- index.html, sw.js, manifest: NEVER cache - must always be fresh -->
                <rule name="No Cache for HTML and SW" preCondition="IsHTMLorSW" stopProcessing="true">
                    <match serverVariable="RESPONSE_Cache-Control" pattern=".*" />
                    <action type="Rewrite" value="no-store, no-cache, must-revalidate" />
                </rule>

                <!-- Hashed assets (Vite output in /assets/): cache 1 year immutable -->
                <rule name="Cache Hashed Assets" preCondition="IsHashedAsset" stopProcessing="true">
                    <match serverVariable="RESPONSE_Cache-Control" pattern=".*" />
                    <action type="Rewrite" value="public, max-age=31536000, immutable" />
                </rule>

                <!-- API responses: NO browser/proxy caching (backend cache handles this) -->
                <rule name="No Cache for API" preCondition="IsAPIRequest">
                    <match serverVariable="RESPONSE_Cache-Control" pattern=".*" />
                    <action type="Rewrite" value="no-store, no-cache, must-revalidate, proxy-revalidate" />
                </rule>

                <preConditions>
                    <preCondition name="IsHTTPS">
                        <add input="{HTTPS}" pattern="on" />
                    </preCondition>
                    <preCondition name="IsHTMLorSW">
                        <add input="{URL}" pattern="(index\.html|sw\.js|manifest\.json|\.webmanifest)$" />
                    </preCondition>
                    <preCondition name="IsHashedAsset">
                        <add input="{URL}" pattern="/assets/" />
                    </preCondition>
                    <preCondition name="IsAPIRequest">
                        <add input="{URL}" pattern="^/api/" />
                    </preCondition>
                </preConditions>
            </outboundRules>
        </rewrite>

        <!-- Error Pages -->
        <httpErrors errorMode="Custom" existingResponse="Replace">
            <!-- 404 - Not Found: Serve index.html for SPA routing -->
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" path="index.html" responseMode="ExecuteURL" />

            <!-- 500 - Internal Server Error -->
            <remove statusCode="500" subStatusCode="-1" />
            <error statusCode="500" path="index.html" responseMode="ExecuteURL" />
        </httpErrors>

        <!-- Disable directory browsing -->
        <directoryBrowse enabled="false" />

    </system.webServer>

    <!-- System.web for ASP.NET settings (if needed) -->
    <system.web>
        <compilation debug="false" targetFramework="4.8" />
        <httpRuntime targetFramework="4.8" maxRequestLength="10240" executionTimeout="300" />
    </system.web>

</configuration>
