"""Tests for file management routes."""

import uuid

import pytest
from fastapi import HTTPException
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.agent import Agent
from app.models.task import Task
from app.models.tenant import Tenant
from app.routes.files import inspect_file
from app.schemas.file import FileInspectRequest


@pytest.mark.asyncio
class TestInspectFile:
    """Tests for the inspect_file endpoint."""

    async def test_happy_path(
        self, db: AsyncSession, test_tenant: Tenant, test_agent: Agent
    ):
        """Valid request creates a FILE_INSPECT task."""
        request = FileInspectRequest(
            tenant_id=test_tenant.id,
            path="/opt/letsbe/data/config.json",
            max_bytes=4096,
        )

        task = await inspect_file(agent_id=test_agent.id, request=request, db=db)

        assert task.id is not None
        assert task.tenant_id == test_tenant.id
        assert task.agent_id == test_agent.id
        assert task.type == "FILE_INSPECT"
        assert task.status == "pending"
        assert task.payload["path"] == "/opt/letsbe/data/config.json"
        assert task.payload["max_bytes"] == 4096

    async def test_with_default_max_bytes(
        self, db: AsyncSession, test_tenant: Tenant, test_agent: Agent
    ):
        """Request uses default max_bytes of 4096."""
        request = FileInspectRequest(
            tenant_id=test_tenant.id,
            path="/opt/letsbe/data/config.json",
        )

        task = await inspect_file(agent_id=test_agent.id, request=request, db=db)

        assert task.type == "FILE_INSPECT"
        assert task.payload["path"] == "/opt/letsbe/data/config.json"
        assert task.payload["max_bytes"] == 4096

    async def test_with_custom_max_bytes(
        self, db: AsyncSession, test_tenant: Tenant, test_agent: Agent
    ):
        """Request with custom max_bytes is respected."""
        request = FileInspectRequest(
            tenant_id=test_tenant.id,
            path="/opt/letsbe/data/large_file.txt",
            max_bytes=1048576,  # 1MB
        )

        task = await inspect_file(agent_id=test_agent.id, request=request, db=db)

        assert task.type == "FILE_INSPECT"
        assert task.payload["max_bytes"] == 1048576

    async def test_tenant_not_found(self, db: AsyncSession, test_agent: Agent):
        """Returns 404 when tenant doesn't exist."""
        fake_tenant_id = uuid.uuid4()
        request = FileInspectRequest(
            tenant_id=fake_tenant_id,
            path="/opt/letsbe/data/config.json",
        )

        with pytest.raises(HTTPException) as exc_info:
            await inspect_file(agent_id=test_agent.id, request=request, db=db)

        assert exc_info.value.status_code == 404
        assert f"Tenant {fake_tenant_id} not found" in str(exc_info.value.detail)

    async def test_agent_not_found(self, db: AsyncSession, test_tenant: Tenant):
        """Returns 404 when agent doesn't exist."""
        fake_agent_id = uuid.uuid4()
        request = FileInspectRequest(
            tenant_id=test_tenant.id,
            path="/opt/letsbe/data/config.json",
        )

        with pytest.raises(HTTPException) as exc_info:
            await inspect_file(agent_id=fake_agent_id, request=request, db=db)

        assert exc_info.value.status_code == 404
        assert f"Agent {fake_agent_id} not found" in str(exc_info.value.detail)

    async def test_task_persisted_to_database(
        self, db: AsyncSession, test_tenant: Tenant, test_agent: Agent
    ):
        """Verify the task is actually persisted and can be retrieved."""
        request = FileInspectRequest(
            tenant_id=test_tenant.id,
            path="/opt/letsbe/data/config.json",
        )

        task = await inspect_file(agent_id=test_agent.id, request=request, db=db)

        # Query the task back from the database
        result = await db.execute(select(Task).where(Task.id == task.id))
        retrieved_task = result.scalar_one_or_none()

        assert retrieved_task is not None
        assert retrieved_task.type == "FILE_INSPECT"
        assert retrieved_task.tenant_id == test_tenant.id
