"""Tests for CLI stream subcommand."""

from __future__ import annotations

import json
import sys
from unittest import mock

import pytest

from orxaq.experiences import cli as cli_mod


@pytest.fixture(autouse=True)
def _tmp_db(tmp_path, monkeypatch):
    """Create a temp DB with snapshots for stream tests."""
    db_file = tmp_path / "stream.db"
    from orxaq.fabric.persistence import SQLiteStore

    with SQLiteStore(str(db_file)) as store:
        store.save_dag_snapshot("v1", '{"n":1}')
        store.save_dag_snapshot("v2", '{"n":2}')

    monkeypatch.setattr(cli_mod, "_get_db_path", lambda _a: str(db_file))


class TestCLIStreamECL:
    def test_stream_ecl_ndjson(self, capsys):
        with mock.patch.object(sys, "argv", ["orxaq", "stream", "ecl"]):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        # Should have NDJSON lines
        lines = [ln for ln in out.strip().split("\n") if ln]
        for line in lines:
            parsed = json.loads(line)
            assert "segment" in parsed

    def test_stream_ecl_sse(self, capsys):
        with mock.patch.object(sys, "argv", ["orxaq", "stream", "ecl", "--format", "sse"]):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "event: result" in out
        assert "event: done" in out

    def test_stream_ecl_json(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            ["orxaq", "--json", "stream", "ecl", "--format", "json"],
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "records" in data
        assert "count" in data

    def test_stream_ecl_paginated(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            [
                "orxaq",
                "--json",
                "stream",
                "ecl",
                "--page",
                "1",
                "--page-size",
                "2",
            ],
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["page"] == 1
        assert len(data["records"]) <= 2


class TestCLIStreamSnapshots:
    def test_stream_snapshots_ndjson(self, capsys):
        with mock.patch.object(sys, "argv", ["orxaq", "stream", "snapshots"]):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        lines = [ln for ln in out.strip().split("\n") if ln]
        assert len(lines) == 2

    def test_stream_snapshots_sse(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            ["orxaq", "stream", "snapshots", "--format", "sse"],
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "event: result" in out
        assert "event: done" in out

    def test_stream_snapshots_json(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            ["orxaq", "--json", "stream", "snapshots", "--format", "json"],
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["count"] == 2
