"""
WebDAV 文件管理路由
使用 WsgiDAV 开源库提供完整的 WebDAV 协议支持
为 projects/{resource_type}/ 目录提供 WebDAV 协议支持
支持的资源类型: 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"}

# 确保基础目录存在
for resource_type in ALLOWED_RESOURCE_TYPES:
    (PROJECTS_BASE_DIR / resource_type).mkdir(parents=True, exist_ok=True)

# 构建 provider_mapping：每个资源类型映射到对应目录
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 中间件：处理反向代理场景下 Destination 头的 scheme/host 不匹配问题。

    当服务运行在 HTTPS 反向代理后面时，客户端发送的 Destination 头包含外部 URL
    （如 https://example.com/webdav/docs/new-name），但 WsgiDAV 内部看到的是 HTTP。
    这个中间件将 Destination 头重写为与内部请求一致的 scheme 和 host。
    """
    # 从 X-Forwarded 头获取外部信息，并确保 wsgi.url_scheme 正确
    forwarded_proto = environ.get("HTTP_X_FORWARDED_PROTO")
    if forwarded_proto:
        environ["wsgi.url_scheme"] = forwarded_proto

    # 重写 Destination 头：将外部 scheme/host 替换为内部实际值
    destination = environ.get("HTTP_DESTINATION")
    if destination:
        parsed = urlparse(destination)
        # 用内部实际的 scheme 和 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)
