"""Unit tests for the FileManager helper."""

from __future__ import annotations

import logging
from typing import Iterable

import pytest

from hel_elmuro.file_manager import FileManager


logger = logging.getLogger(__name__)

ACCOUNT_NAME = "sampleaccount"
ACCOUNT_KEY = "sekret=="
CONTAINER_NAME = "analytics"
REPORTS_PREFIX = "reports/"
SAMPLE_BLOB_PATH = f"{REPORTS_PREFIX}2025-01.csv"
SAMPLE_BLOB_CONTENT = b"col_a,col_b\n1,2\n"


class StubBlobClient:
    """Stub blob client supporting list and download operations."""

    def __init__(self, name: str, content: bytes) -> None:
        self.name = name
        self._content = content
        self.download_calls = 0

    def download_blob(self) -> "StubBlobClient":
        self.download_calls += 1
        return self

    def readall(self) -> bytes:
        return self._content


class StubBlobProperties:
    """Tiny wrapper carrying the blob name for the stub iterator."""

    def __init__(self, name: str) -> None:
        self.name = name


class StubContainerClient:
    """Stub container client that records prefixes and blob requests."""

    def __init__(self, blob_map: dict[str, StubBlobClient]) -> None:
        self._blob_map = blob_map
        self.requested_prefixes: list[str] = []
        self.requested_blob_names: list[str] = []

    def list_blobs(self, name_starts_with: str = "") -> Iterable[StubBlobProperties]:
        self.requested_prefixes.append(name_starts_with)
        for blob_name in self._blob_map:
            if blob_name.startswith(name_starts_with):
                yield StubBlobProperties(blob_name)

    def get_blob_client(self, blob_path: str) -> StubBlobClient:
        self.requested_blob_names.append(blob_path)
        return self._blob_map[blob_path]


class StubBlobServiceClient:
    """Stub implementation returning the supplied container client."""

    def __init__(self, container_client: StubContainerClient) -> None:
        self._container_client = container_client
        self.requested_container: str | None = None

    def get_container_client(self, container_name: str) -> StubContainerClient:
        self.requested_container = container_name
        return self._container_client


@pytest.fixture()
def stub_blob_service(monkeypatch: pytest.MonkeyPatch) -> tuple[StubContainerClient, dict[str, str], StubBlobServiceClient]:
    """Provide a stubbed BlobServiceClient and capture the connection string used."""
    blob_map = {
        SAMPLE_BLOB_PATH: StubBlobClient(name=SAMPLE_BLOB_PATH, content=SAMPLE_BLOB_CONTENT),
        f"{REPORTS_PREFIX}2025-02.csv": StubBlobClient(name=f"{REPORTS_PREFIX}2025-02.csv", content=b""),
        "logs/raw.txt": StubBlobClient(name="logs/raw.txt", content=b"log"),
    }
    container_client = StubContainerClient(blob_map=blob_map)
    captured: dict[str, str] = {}
    stub_service = StubBlobServiceClient(container_client)

    def fake_from_connection_string(connection_string: str) -> StubBlobServiceClient:
        captured["connection_string"] = connection_string
        return stub_service

    monkeypatch.setattr("hel_elmuro.file_manager.BlobServiceClient.from_connection_string", fake_from_connection_string)
    return container_client, captured, stub_service


def test_file_manager_counts_filtered_blobs(
    stub_blob_service: tuple[StubContainerClient, dict[str, str], StubBlobServiceClient]
) -> None:
    """Ensure FileManager builds the connection string and counts prefixed blobs."""
    container_client, captured, stub_service = stub_blob_service
    logger.info("Scenario: FileManager counts filtered blobs and builds connection string inside the constructor.")

    manager = FileManager(account_name=ACCOUNT_NAME, account_key=ACCOUNT_KEY, container_name=CONTAINER_NAME)

    count = manager.count_files(prefix=REPORTS_PREFIX)

    assert count == 2
    assert container_client.requested_prefixes == [REPORTS_PREFIX]
    assert stub_service.requested_container == CONTAINER_NAME
    assert captured["connection_string"] == (
        "DefaultEndpointsProtocol=https;"
        f"AccountName={ACCOUNT_NAME};"
        f"AccountKey={ACCOUNT_KEY};"
        "EndpointSuffix=core.windows.net"
    )


def test_file_manager_downloads_blob_bytes(
    stub_blob_service: tuple[StubContainerClient, dict[str, str], StubBlobServiceClient]
) -> None:
    """Ensure FileManager can download blob content as bytes."""
    container_client, _, _ = stub_blob_service
    logger.info("Scenario: FileManager downloads blob content for downstream processing.")

    manager = FileManager(account_name=ACCOUNT_NAME, account_key=ACCOUNT_KEY, container_name=CONTAINER_NAME)

    payload = manager.download_bytes(SAMPLE_BLOB_PATH)

    assert payload == SAMPLE_BLOB_CONTENT
    assert container_client.requested_blob_names == [SAMPLE_BLOB_PATH]
    assert container_client._blob_map[SAMPLE_BLOB_PATH].download_calls == 1
