import cv2
import numpy as np
import pytest


@pytest.mark.parametrize(
    "dataset_fixture",
    ["simple_dataset_native", "simple_dataset_cloud"],
)
def test_video_basics(request, dataset_fixture):
    dataset = request.getfixturevalue(dataset_fixture)
    for recording in dataset.recordings:
        eye_video = None
        video = None
        try:
            if dataset_fixture == "simple_dataset_cloud":
                with pytest.raises(
                    ValueError,
                    match=(
                        "Recording.eye_video cannot be read because: "
                        "Pupil Cloud recordings do not contain eye video."
                    ),
                ):
                    eye_video = recording.eye_video
            else:
                eye_video = recording.eye_video
                assert eye_video.info == {}

            video = recording.scene_video
            n_frames = len(video.ts)
            assert n_frames == video.get(cv2.CAP_PROP_FRAME_COUNT)

            # Select random frames within n_frames and always test first and last frame
            random_frames = np.random.choice(n_frames, size=10, replace=False)
            random_frames = np.append(random_frames, [0, n_frames - 1])
            for frame_idx in random_frames:
                frame_idx = int(frame_idx)
                frame = video.read_frame_at(frame_idx)
                assert frame_idx == video.current_frame_index
                if frame_idx == 0:
                    assert frame is None
                else:
                    assert frame.shape == (video.height, video.width, 3)

            with pytest.raises(ValueError, match="is out of bounds."):
                video.read_frame_at(-5)
                video.read_frame_at(n_frames + 1)
        finally:
            if eye_video is not None:
                eye_video.close()
            if video is not None:
                video.close()
