"""Tests for recording functionality."""

import os
import time
import asyncio
import pytest
from grasp import Grasp, AsyncGrasp


class TestRecording:
    """Test synchronous recording functionality."""

    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_recording_exists(self):
        """Test that recording manager is accessible from container."""
        container = self.grasp.create()
        try:
            assert hasattr(container.browser, 'recording')
            assert container.browser.recording is not None
        finally:
            container.shutdown()

    def test_start_recording(self):
        """Test starting a recording."""
        container = self.grasp.create()
        try:
            recording = container.browser.recording.start(
                format="mp4",
                framerate=30,
                quality="medium",
            )

            assert recording is not None
            assert recording.id is not None
            assert recording.status in ["recording", "finished"]
            assert recording.format == "mp4"
            assert recording.framerate == 30
            assert recording.resolution is not None
            assert recording.started_at is not None

            stopped_recording = container.browser.recording.stop(recording.id)
            assert stopped_recording.id == recording.id
            assert stopped_recording.status in ["uploading", "finished"]
        finally:
            container.shutdown()

    def test_start_recording_with_options(self):
        """Test starting a recording with various options."""
        container = self.grasp.create()
        try:
            recording = container.browser.recording.start(
                format="mp4",
                framerate=15,
                quality="low",
                resolution="1280x720",
                audio=False,
                max_duration=10000,
            )

            assert recording is not None
            assert recording.id is not None
            assert recording.format == "mp4"
            assert recording.framerate == 15
            assert recording.resolution == "1280x720"

            container.browser.recording.stop(recording.id)
        finally:
            container.shutdown()

    def test_stop_recording(self):
        """Test stopping a recording."""
        container = self.grasp.create()
        try:
            recording = container.browser.recording.start()
            time.sleep(2)

            stopped_recording = container.browser.recording.stop(recording.id)

            assert stopped_recording.id == recording.id
            assert stopped_recording.status in ["uploading", "finished"]
            assert stopped_recording.stopped_at is not None
        finally:
            container.shutdown()

    def test_get_recording_info(self):
        """Test getting recording information."""
        container = self.grasp.create()
        try:
            recording = container.browser.recording.start()
            time.sleep(1)
            container.browser.recording.stop(recording.id)

            info = container.browser.recording.get(recording.id)

            assert info is not None
            assert info.id == recording.id
            assert info.status in ["uploading", "finished"]
            assert info.filename is not None
            assert info.local_path is not None
        finally:
            container.shutdown()

    def test_get_all_recordings(self):
        """Test listing all recordings."""
        container = self.grasp.create()
        recordings = []
        try:
            for i in range(2):
                rec = container.browser.recording.start()
                recordings.append(rec)
                time.sleep(1)
                container.browser.recording.stop(rec.id)
                time.sleep(0.5)

            all_recordings = container.browser.recording.get_all()

            assert all_recordings is not None
            assert len(all_recordings) >= 2
            recording_ids = [r.id for r in all_recordings]
            for rec in recordings:
                assert rec.id in recording_ids
        finally:
            container.shutdown()

    def test_get_recordings_by_status(self):
        """Test filtering recordings by status."""
        container = self.grasp.create()
        try:
            recording = container.browser.recording.start()
            time.sleep(1)
            container.browser.recording.stop(recording.id)
            time.sleep(2)

            finished_recordings = container.browser.recording.get_all(status="finished")

            assert finished_recordings is not None
            assert isinstance(finished_recordings, list)
            for rec in finished_recordings:
                assert rec.status == "finished"
        finally:
            container.shutdown()

    def test_error_stop_nonexistent_recording(self):
        """Test error when stopping nonexistent recording."""
        container = self.grasp.create()
        try:
            with pytest.raises(Exception):
                container.browser.recording.stop("nonexistent-recording-id")
        finally:
            container.shutdown()

    def test_error_get_nonexistent_recording(self):
        """Test error when getting nonexistent recording."""
        container = self.grasp.create()
        try:
            with pytest.raises(Exception):
                container.browser.recording.get("nonexistent-recording-id")
        finally:
            container.shutdown()


@pytest.mark.asyncio
class TestAsyncRecording:
    """Test asynchronous recording functionality."""

    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_recording_exists(self):
        """Test that recording manager is accessible from container."""
        container = await self.grasp.create()
        try:
            assert hasattr(container.browser, 'recording')
            assert container.browser.recording is not None
        finally:
            await container.shutdown()

    async def test_start_recording(self):
        """Test starting a recording."""
        container = await self.grasp.create()
        try:
            recording = await container.browser.recording.start(
                format="mp4",
                framerate=30,
                quality="medium",
            )

            assert recording is not None
            assert recording.id is not None
            assert recording.status in ["recording", "finished"]
            assert recording.format == "mp4"
            assert recording.framerate == 30
            assert recording.resolution is not None
            assert recording.started_at is not None

            stopped_recording = await container.browser.recording.stop(recording.id)
            assert stopped_recording.id == recording.id
            assert stopped_recording.status in ["uploading", "finished"]
        finally:
            await container.shutdown()

    async def test_start_recording_with_options(self):
        """Test starting a recording with various options."""
        container = await self.grasp.create()
        try:
            recording = await container.browser.recording.start(
                format="mp4",
                framerate=15,
                quality="low",
                resolution="1280x720",
                audio=False,
                max_duration=10000,
            )

            assert recording is not None
            assert recording.id is not None
            assert recording.format == "mp4"
            assert recording.framerate == 15
            assert recording.resolution == "1280x720"

            await container.browser.recording.stop(recording.id)
        finally:
            await container.shutdown()

    async def test_stop_recording(self):
        """Test stopping a recording."""
        container = await self.grasp.create()
        try:
            recording = await container.browser.recording.start()
            await asyncio.sleep(2)

            stopped_recording = await container.browser.recording.stop(recording.id)

            assert stopped_recording.id == recording.id
            assert stopped_recording.status in ["uploading", "finished"]
            assert stopped_recording.stopped_at is not None
        finally:
            await container.shutdown()

    async def test_get_recording_info(self):
        """Test getting recording information."""
        container = await self.grasp.create()
        try:
            recording = await container.browser.recording.start()
            await asyncio.sleep(1)
            await container.browser.recording.stop(recording.id)

            info = await container.browser.recording.get(recording.id)

            assert info is not None
            assert info.id == recording.id
            assert info.status in ["uploading", "finished"]
            assert info.filename is not None
            assert info.local_path is not None
        finally:
            await container.shutdown()

    async def test_get_all_recordings(self):
        """Test listing all recordings."""
        container = await self.grasp.create()
        recordings = []
        try:
            for i in range(2):
                rec = await container.browser.recording.start()
                recordings.append(rec)
                await asyncio.sleep(1)
                await container.browser.recording.stop(rec.id)
                await asyncio.sleep(0.5)

            all_recordings = await container.browser.recording.get_all()

            assert all_recordings is not None
            assert len(all_recordings) >= 2
            recording_ids = [r.id for r in all_recordings]
            for rec in recordings:
                assert rec.id in recording_ids
        finally:
            await container.shutdown()

    async def test_get_recordings_by_status(self):
        """Test filtering recordings by status."""
        container = await self.grasp.create()
        try:
            recording = await container.browser.recording.start()
            await asyncio.sleep(1)
            await container.browser.recording.stop(recording.id)
            await asyncio.sleep(2)

            finished_recordings = await container.browser.recording.get_all(status="finished")

            assert finished_recordings is not None
            assert isinstance(finished_recordings, list)
            for rec in finished_recordings:
                assert rec.status == "finished"
        finally:
            await container.shutdown()

    async def test_error_stop_nonexistent_recording(self):
        """Test error when stopping nonexistent recording."""
        container = await self.grasp.create()
        try:
            with pytest.raises(Exception):
                await container.browser.recording.stop("nonexistent-recording-id")
        finally:
            await container.shutdown()

    async def test_error_get_nonexistent_recording(self):
        """Test error when getting nonexistent recording."""
        container = await self.grasp.create()
        try:
            with pytest.raises(Exception):
                await container.browser.recording.get("nonexistent-recording-id")
        finally:
            await container.shutdown()

    async def test_sequential_recordings(self):
        """Test creating multiple recordings sequentially on the same container."""
        container = await self.grasp.create()
        recordings = []
        try:
            for i in range(2):
                rec = await container.browser.recording.start()
                recordings.append(rec)
                await asyncio.sleep(1)
                stopped = await container.browser.recording.stop(rec.id)
                await asyncio.sleep(0.5)

                assert stopped is not None
                assert stopped.id is not None
                assert stopped.status in ["uploading", "finished"]

            all_recs = await container.browser.recording.get_all()
            recording_ids = [r.id for r in all_recs]
            for rec in recordings:
                assert rec.id in recording_ids
        finally:
            await container.shutdown()
