"""
WebDAV file management routes.
Uses the open-source WsgiDAV library to provide full WebDAV protocol support.
Provides WebDAV access for the projects/{resource_type}/ directories.
Supported resource types: robot, docs
"""

from pathlib import Path
from urllib.parse import urlparse, urlunparse

from wsgidav.wsgidav_app import WsgiDAVApp
from wsgidav.fs_dav_provider import FilesystemProvider

from utils.settings import WEBDAV_USERNAME, WEBDAV_PASSWORD

PROJECTS_BASE_DIR = Path("projects")
ALLOWED_RESOURCE_TYPES = {"robot", "docs"}

# Ensure the base directories exist
for resource_type in ALLOWED_RESOURCE_TYPES:
    (PROJECTS_BASE_DIR / resource_type).mkdir(parents=True, exist_ok=True)

# Build provider_mapping: map each resource type to its corresponding directory
provider_mapping = {}
for resource_type in ALLOWED_RESOURCE_TYPES:
    abs_path = str((PROJECTS_BASE_DIR / resource_type).resolve())
    provider_mapping[f"/{resource_type}"] = FilesystemProvider(abs_path)

config = {
    "mount_path": "/webdav",
    "provider_mapping": provider_mapping,
    "http_authenticator": {
        "domain_controller": "wsgidav.dc.simple_dc.SimpleDomainController",
        "accept_basic": True,
        "accept_digest": False,
        "default_to_digest": False,
    },
    "simple_dc": {
        "user_mapping": {
            "*": {
                WEBDAV_USERNAME: {
                    "password": WEBDAV_PASSWORD,
                },
            },
        },
    },
    "verbose": 1,
    "lock_storage": True,
    "property_manager": True,
    "dir_browser": {
        "enable": True,
        "icon": True,
        "response_trailer": "",
    },
    "hotfixes": {
        "re_encode_path_info": True,
    },
}

_wsgidav_app = WsgiDAVApp(config)


def wsgidav_app(environ, start_response):
    """WSGI middleware that fixes Destination header scheme/host mismatches behind a reverse proxy.

    When the service runs behind an HTTPS reverse proxy, the client sends a Destination
    header with the external URL (for example https://example.com/webdav/docs/new-name),
    while WsgiDAV internally sees an HTTP request. This middleware rewrites the
    Destination header so its scheme and host match the internal request.
    """
    # Read external request information from X-Forwarded headers and keep
    # wsgi.url_scheme aligned with the forwarded protocol.
    forwarded_proto = environ.get("HTTP_X_FORWARDED_PROTO")
    if forwarded_proto:
        environ["wsgi.url_scheme"] = forwarded_proto

    # Rewrite the Destination header by replacing the external scheme/host
    # with the internal values observed by the application.
    destination = environ.get("HTTP_DESTINATION")
    if destination:
        parsed = urlparse(destination)
        # Replace with the actual internal scheme and host.
        internal_scheme = environ.get("wsgi.url_scheme", "http")
        internal_host = environ.get("HTTP_HOST", environ.get("SERVER_NAME", "localhost"))
        rewritten = urlunparse((
            internal_scheme,
            internal_host,
            parsed.path,
            parsed.params,
            parsed.query,
            parsed.fragment,
        ))
        environ["HTTP_DESTINATION"] = rewritten

    return _wsgidav_app(environ, start_response)
