from __future__ import annotations

from email.utils import formatdate
from pathlib import Path

from .exceptions import NotFound
from .response import FileResponse


def send_from_directory(
    directory: str | Path,
    filename: str,
    *,
    max_age: int = 3600,
) -> FileResponse:
    base = Path(directory).resolve()
    target = (base / filename).resolve()

    if not _is_relative_to(target, base):
        raise NotFound()
    if not target.exists() or not target.is_file():
        raise NotFound()
    return FileResponse(target, headers=_build_cache_headers(target, max_age=max_age))


def _build_cache_headers(path: Path, *, max_age: int) -> dict[str, str]:
    stat = path.stat()
    normalized_max_age = max(0, int(max_age))
    etag = f'W/"{int(stat.st_mtime)}-{stat.st_size}"'
    return {
        "Cache-Control": f"public, max-age={normalized_max_age}",
        "Last-Modified": formatdate(stat.st_mtime, usegmt=True),
        "ETag": etag,
    }


def _is_relative_to(path: Path, parent: Path) -> bool:
    try:
        path.relative_to(parent)
        return True
    except ValueError:
        return False
