"""Tests for container lifecycle operations."""

import os
import pytest
from grasp import Grasp, AsyncGrasp


class TestContainerLifecycle:
    """Test container lifecycle operations."""

    def setup_method(self, method):
        """Setup before each test method."""
        self.grasp = Grasp(
            api_key=os.environ["GRASP_API_KEY"],
            base_url=os.environ["GRASP_BASE_URL"],
        )

    def test_create_container(self):
        """Test creating a new container."""
        container = self.grasp.create()

        try:
            assert container.id is not None
            assert isinstance(container.id, str)
            assert container.status == "started"
            assert container.created_at is not None
            assert container.browser.ws_endpoint is not None
            assert container.browser.ws_endpoint.startswith(("ws://", "wss://"))
            assert container.browser.live_url is not None
            assert container.browser.live_url.startswith(("http://", "https://"))
        finally:
            container.shutdown()

    def test_create_container_with_idle_timeout(self):
        """Test creating container with idle timeout option."""
        container = self.grasp.create(idle_timeout=60000)

        try:
            assert container.id is not None
            assert container.status == "started"
        finally:
            container.shutdown()

    def test_connect_to_container(self):
        """Test connecting to existing container by ID."""
        new_container = self.grasp.create()

        try:
            container_id = new_container.id
            connected_container = self.grasp.connect(container_id)

            assert connected_container.id == container_id
            assert connected_container.browser.ws_endpoint is not None
            assert connected_container.browser.live_url is not None
        finally:
            new_container.shutdown()

    def test_shutdown_container(self):
        """Test shutting down a container."""
        container = self.grasp.create()
        # Should not raise any exception
        container.shutdown()

    def test_serialize_container_without_api_key(self):
        """Test container serialization without API key."""
        container = self.grasp.create()

        try:
            serialized = container.to_dict()

            assert serialized is not None
            assert serialized["id"] == container.id
            assert serialized["status"] == container.status
            assert serialized["created_at"] == container.created_at
            assert serialized["base_url"] == container._base_url
            assert serialized["browser"] is not None
            assert serialized["browser"]["ws_endpoint"] == container.browser.ws_endpoint
            assert serialized["browser"]["live_url"] == container.browser.live_url
            # API key should not be in serialized data
            assert "api_key" not in serialized
        finally:
            container.shutdown()


@pytest.mark.asyncio
class TestAsyncContainerLifecycle:
    """Test async container lifecycle operations."""

    def setup_method(self, method):
        """Setup before each test method."""
        self.grasp = AsyncGrasp(
            api_key=os.environ["GRASP_API_KEY"],
            base_url=os.environ["GRASP_BASE_URL"],
        )

    async def test_create_container(self):
        """Test creating a new container."""
        container = await self.grasp.create()

        try:
            assert container.id is not None
            assert isinstance(container.id, str)
            assert container.status == "started"
            assert container.created_at is not None
            assert container.browser.ws_endpoint is not None
            assert container.browser.ws_endpoint.startswith(("ws://", "wss://"))
            assert container.browser.live_url is not None
            assert container.browser.live_url.startswith(("http://", "https://"))
        finally:
            await container.shutdown()

    async def test_create_container_with_idle_timeout(self):
        """Test creating container with idle timeout option."""
        container = await self.grasp.create(idle_timeout=60000)

        try:
            assert container.id is not None
            assert container.status == "started"
        finally:
            await container.shutdown()

    async def test_connect_to_container(self):
        """Test connecting to existing container by ID."""
        new_container = await self.grasp.create()

        try:
            container_id = new_container.id
            connected_container = await self.grasp.connect(container_id)

            assert connected_container.id == container_id
            assert connected_container.browser.ws_endpoint is not None
            assert connected_container.browser.live_url is not None
        finally:
            await new_container.shutdown()

    async def test_shutdown_container(self):
        """Test shutting down a container."""
        container = await self.grasp.create()
        # Should not raise any exception
        await container.shutdown()

    async def test_serialize_container_without_api_key(self):
        """Test container serialization without API key."""
        container = await self.grasp.create()

        try:
            serialized = container.to_dict()

            assert serialized is not None
            assert serialized["id"] == container.id
            assert serialized["status"] == container.status
            assert serialized["created_at"] == container.created_at
            assert serialized["base_url"] == container._base_url
            assert serialized["browser"] is not None
            assert serialized["browser"]["ws_endpoint"] == container.browser.ws_endpoint
            assert serialized["browser"]["live_url"] == container.browser.live_url
            # API key should not be in serialized data
            assert "api_key" not in serialized
        finally:
            await container.shutdown()

    async def test_context_manager(self):
        """Test using async client as context manager."""
        async with AsyncGrasp(
            api_key=os.environ["GRASP_API_KEY"],
            base_url=os.environ["GRASP_BASE_URL"],
        ) as client:
            container = await client.create()
            assert container.id is not None
            await container.shutdown()
        # Client should be closed automatically
