"""
Custom views for serving files with Unicode filename support.
"""
import os
import mimetypes
from django.http import FileResponse, Http404
from django.utils.http import http_date
from django.views.static import was_modified_since
from pathlib import Path


def serve_unicode(request, path, document_root=None):
    """
    Serve static files, handling Unicode filenames correctly under Apache/WSGI.

    This is a modified version of django.views.static.serve that properly
    handles UTF-8 filenames in Apache/WSGI environments where the default
    encoding is ASCII.
    """
    # Reconstruct the full path
    path = path.lstrip('/')

    if document_root is not None:
        # Handle Unicode path encoding issues in Apache/WSGI
        if isinstance(path, str):
            try:
                # Fix UTF-8 mojibake: UTF-8 bytes incorrectly decoded as Latin-1
                path = path.encode('latin-1').decode('utf-8')
            except (UnicodeDecodeError, UnicodeEncodeError):
                # Path is already correctly decoded
                pass

        # Security check - ensure path doesn't contain '..'
        if '..' in path.split('/'):
            raise Http404("Invalid path")

        # Build full path as string first
        fullpath_str = os.path.join(document_root, path)

        # Normalize the path
        fullpath_str = os.path.normpath(fullpath_str)

        # Verify it's still within document_root
        if not fullpath_str.startswith(os.path.normpath(document_root)):
            raise Http404("Invalid path")

        # Encode to UTF-8 bytes explicitly for filesystem operations
        try:
            fullpath_bytes = fullpath_str.encode('utf-8')
        except UnicodeEncodeError:
            raise Http404("Invalid filename encoding")

        # Check if file exists using bytes path
        try:
            if not os.path.exists(fullpath_bytes):
                raise Http404("File not found")

            if not os.path.isfile(fullpath_bytes):
                raise Http404("Not a file")
        except OSError:
            raise Http404("File access error")

        # Get file stats using bytes path
        try:
            statobj = os.stat(fullpath_bytes)
        except OSError:
            raise Http404("Cannot access file")

        # Check if-modified-since header
        if not was_modified_since(
            request.META.get('HTTP_IF_MODIFIED_SINCE'),
            statobj.st_mtime
        ):
            from django.http import HttpResponseNotModified
            return HttpResponseNotModified()

        # Determine content type
        content_type, encoding = mimetypes.guess_type(fullpath_str)
        content_type = content_type or 'application/octet-stream'

        # Open file using bytes path to avoid encoding issues
        try:
            # Use the byte path for opening
            response = FileResponse(open(fullpath_bytes, 'rb'), content_type=content_type)
        except OSError:
            raise Http404("Cannot read file")

        response['Last-Modified'] = http_date(statobj.st_mtime)

        # Handle Content-Disposition for download
        if 'filename' in request.GET:
            filename = request.GET['filename']
            # Encode filename for Content-Disposition header (RFC 6266)
            response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{filename}'

        response['Content-Length'] = statobj.st_size

        if encoding:
            response['Content-Encoding'] = encoding

        return response

    raise Http404("Document root not specified")
