from __future__ import annotations
import os
import tempfile
from datetime import datetime
from pathlib import Path, PurePosixPath

from govcrawler.settings import get_settings
from govcrawler.storage.paths import build_reldir, to_os_path


def _atomic_write_bytes(path: Path, data: bytes) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    fd, tmp = tempfile.mkstemp(prefix=".tmp_", dir=str(path.parent))
    try:
        with os.fdopen(fd, "wb") as f:
            f.write(data)
        os.replace(tmp, path)
    except Exception:
        try:
            os.unlink(tmp)
        except FileNotFoundError:
            pass
        raise


def write_raw_html(
    site: str, column: str, when: datetime, article_key: str, html: str
) -> PurePosixPath:
    """Write raw html; return POSIX relative path (stored in DB)."""
    reldir = build_reldir(site, column, when, "raw_html")
    relpath = reldir / f"{article_key}.html"
    abs_path = to_os_path(get_settings().data_dir, relpath)
    _atomic_write_bytes(abs_path, html.encode("utf-8"))
    return relpath


def write_article_text(
    site: str, column: str, when: datetime, article_key: str, text: str
) -> PurePosixPath:
    reldir = build_reldir(site, column, when, "articles_text")
    relpath = reldir / f"{article_key}.txt"
    abs_path = to_os_path(get_settings().data_dir, relpath)
    _atomic_write_bytes(abs_path, text.encode("utf-8"))
    return relpath
