"""Tests for CLI db subcommand -- persistence operations."""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from orxaq.experiences.cli import main


class TestCLIDbSnapshots:
    """Tests for db snapshots and save-snapshot."""

    def test_snapshots_empty(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(["db", "--db", db, "snapshots"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "No snapshots" in out

    def test_save_and_list_snapshot(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(
            [
                "db",
                "--db",
                db,
                "save-snapshot",
                "--name",
                "v1",
            ]
        )
        assert rc == 0
        out = capsys.readouterr().out
        assert "Saved snapshot" in out

        rc2 = main(["db", "--db", db, "snapshots"])
        assert rc2 == 0
        out2 = capsys.readouterr().out
        assert "v1" in out2

    def test_save_snapshot_json(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(
            [
                "--json",
                "db",
                "--db",
                db,
                "save-snapshot",
                "--name",
                "jsnap",
            ]
        )
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["name"] == "jsnap"
        assert "snapshot_id" in data

    def test_snapshots_json(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        main(
            [
                "db",
                "--db",
                db,
                "save-snapshot",
                "--name",
                "x",
            ]
        )
        capsys.readouterr()
        rc = main(["--json", "db", "--db", db, "snapshots"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "snapshots" in data
        assert len(data["snapshots"]) == 1


class TestCLIDbKV:
    """Tests for db get/put."""

    def test_put_and_get(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(["db", "--db", db, "put", "color", "blue"])
        assert rc == 0
        capsys.readouterr()

        rc2 = main(["db", "--db", db, "get", "color"])
        assert rc2 == 0
        out = capsys.readouterr().out
        assert "blue" in out

    def test_get_missing(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(["db", "--db", db, "get", "nope"])
        assert rc == 1
        out = capsys.readouterr().out
        assert "not found" in out.lower()

    def test_get_json(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        main(["db", "--db", db, "put", "k", "v"])
        capsys.readouterr()
        rc = main(["--json", "db", "--db", db, "get", "k"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["key"] == "k"
        assert data["value"] == "v"

    def test_put_json(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(
            [
                "--json",
                "db",
                "--db",
                db,
                "put",
                "k",
                "v",
            ]
        )
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["stored"] is True


class TestCLIDbEvents:
    """Tests for db events."""

    def test_events_empty(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(["db", "--db", db, "events"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "No events" in out

    def test_events_json_empty(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        db = str(tmp_path / "test.db")
        rc = main(["--json", "db", "--db", db, "events"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["events"] == []
