from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
UI_JS = ROOT / "static" / "ui.js"
I18N_JS = ROOT / "static" / "i18n.js"
CONFIG_PY = ROOT / "api" / "config.py"
UPLOAD_PY = ROOT / "api" / "upload.py"


def _function_body(src: str, name: str) -> str:
    marker = f"function {name}"
    start = src.index(marker)
    brace = src.index("{", start)
    depth = 0
    for idx in range(brace, len(src)):
        if src[idx] == "{":
            depth += 1
        elif src[idx] == "}":
            depth -= 1
            if depth == 0:
                return src[brace : idx + 1]
    raise AssertionError(f"{name} function body not found")


def test_upload_limit_constant_matches_server_limit():
    """The browser preflight should read the runtime upload limit."""
    ui = UI_JS.read_text(encoding="utf-8")
    config = CONFIG_PY.read_text(encoding="utf-8")

    assert "window.__HERMES_CONFIG__.maxUploadBytes" in ui
    assert 'MAX_UPLOAD_BYTES = _env_mb_bytes("HERMES_WEBUI_MAX_UPLOAD_MB", 20)' in config


def test_file_picker_rejects_oversize_files_before_queueing():
    """Selecting an oversized file should never add it to pending uploads."""
    src = UI_JS.read_text(encoding="utf-8")
    body = _function_body(src, "addFiles")

    size_gate = body.index("f&&f.size>MAX_UPLOAD_BYTES")
    status_notice = body.index("_showUploadTooLarge(f)")
    push_pending = body.index("S.pendingFiles.push(f)")

    assert size_gate < status_notice < push_pending
    assert "continue;" in body[size_gate:push_pending]


def test_pending_uploads_skip_fetch_for_oversize_files():
    """Restored or queued oversized files should fail locally before fetch()."""
    src = UI_JS.read_text(encoding="utf-8")
    body = _function_body(src, "uploadPendingFiles")

    size_gate = body.index("f&&f.size>MAX_UPLOAD_BYTES")
    form_data = body.index("const fd=new FormData()")
    upload_fetch = body.index("fetch(url")

    assert size_gate < form_data < upload_fetch
    assert "throw new Error(_uploadTooLargeMessage(f))" in body[size_gate:form_data]


def test_upload_too_large_has_user_facing_message():
    """The status toast should explain the upload limit instead of a network reset."""
    i18n = I18N_JS.read_text(encoding="utf-8")
    ui = UI_JS.read_text(encoding="utf-8")

    assert "upload_too_large" in i18n
    assert "Maximum upload size is" in i18n
    assert "_uploadTooLargeMessage(file)" in ui


def test_archive_extraction_limit_tracks_upload_limit():
    """Archive extraction guard should scale with the configured upload limit."""
    upload = UPLOAD_PY.read_text(encoding="utf-8")

    assert "_MAX_EXTRACTED_BYTES = 10 * MAX_UPLOAD_BYTES" in upload
