"""Tests for push staging plain-file upload helpers."""

from __future__ import annotations

import pytest
from fastapi import HTTPException

from server.api.sync_v2 import (
    _persist_staging_files,
    _safe_upload_basename,
    _unique_staging_name,
)


def test_safe_upload_basename_strips_path():
    assert _safe_upload_basename("foo/bar.txt") == "foo_bar.txt"
    assert _safe_upload_basename("  ok.php  ") == "ok.php"


def test_safe_upload_basename_rejects_invalid():
    with pytest.raises(HTTPException) as exc:
        _safe_upload_basename("")
    assert exc.value.status_code == 400
    with pytest.raises(HTTPException):
        _safe_upload_basename(".")


def test_unique_staging_name():
    used = {"a.txt"}
    assert _unique_staging_name("a.txt", used) == "a_2.txt"
    used.add("a_2.txt")
    assert _unique_staging_name("a.txt", used) == "a_3.txt"


@pytest.mark.asyncio
async def test_persist_staging_files_writes_to_staging(tmp_path):
    staging = str(tmp_path / "nexus_upload_abc")

    class FakeUpload:
        def __init__(self, name: str, data: bytes):
            self.filename = name
            self._data = data

        async def read(self):
            return self._data

    items = [
        FakeUpload("a.txt", b"hello"),
        FakeUpload("b.txt", b"world"),
    ]
    meta = await _persist_staging_files(staging, items)

    assert meta["file_count"] == 2
    assert meta["size"] == 10
    assert (tmp_path / "nexus_upload_abc" / "a.txt").read_bytes() == b"hello"
    assert meta["source_path"] == staging


@pytest.mark.asyncio
async def test_persist_staging_files_accepts_any_suffix(tmp_path):
    staging = str(tmp_path / "nexus_upload_xyz")

    class FakeUpload:
        def __init__(self, name: str, data: bytes):
            self.filename = name
            self._data = data

        async def read(self):
            return self._data

    items = [
        FakeUpload("pkg.zip", b"PK"),
        FakeUpload("README", b"no-ext"),
        FakeUpload("data.tar.gz", b"x"),
    ]
    meta = await _persist_staging_files(staging, items)

    assert meta["file_count"] == 3
    assert (tmp_path / "nexus_upload_xyz" / "pkg.zip").exists()
    assert (tmp_path / "nexus_upload_xyz" / "README").exists()
