"""Tests the zorg project's 'db' CLI command."""

from __future__ import annotations

from pathlib import Path
import sqlite3

from _pytest.tmpdir import TempPathFactory
from pytest import fixture
from syrupy.assertion import SnapshotAssertion as Snapshot

from . import common as c


@fixture(name="sql_cursor", scope="session")
def sql_cursor_fixture(
    main: c.MainType, tmp_path_factory: TempPathFactory, zettel_dir: Path
) -> sqlite3.Cursor:
    """Connects to the zorg DB created by 'zorg db create'."""
    tmp_path = tmp_path_factory.getbasetemp()
    db_path_str = f"{tmp_path}/zorg.db"
    exit_code = main(
        "--dir",
        str(zettel_dir),
        "db",
        "create",
        database_url=f"sqlite:///{db_path_str}",
    )
    assert exit_code == 0
    conn = sqlite3.connect(db_path_str)
    return conn.cursor()


def test_run_db_create__table_names(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check the SQL table names generated by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM sqlite_master WHERE type = 'table'")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__file_count(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check the number of *.zo files indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT COUNT(*) FROM zorgfile")
    assert snapshot == sql_cursor.fetchone()[0]


def test_run_db_create__note_count(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check the number of zorg notes indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT COUNT(*) FROM zorgnote")
    assert snapshot == sql_cursor.fetchone()[0]


def test_run_db_create__todo_count(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check the number of zorg todos indexed by running 'zorg db create'."""
    sql_cursor.execute(
        "SELECT COUNT(*) FROM zorgnote WHERE todo_status IS NOT NULL"
    )
    assert snapshot == sql_cursor.fetchone()[0]


def test_run_db_create__projects(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what projects are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM project")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__areas(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what areas are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM area")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__people(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what people are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM person")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__contexts(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what contexts are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM context")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__properties(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what properties are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT name FROM property")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__create_dates(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what create dates are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT DISTINCT create_date FROM zorgnote")
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__todo_priorities(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what todo priorities are indexed by running 'zorg db create'."""
    sql_cursor.execute(
        "SELECT DISTINCT todo_priority FROM zorgnote WHERE todo_priority IS"
        " NOT NULL"
    )
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__todo_statuses(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what todo statuses are indexed by running 'zorg db create'."""
    sql_cursor.execute(
        "SELECT DISTINCT todo_status FROM zorgnote WHERE todo_status IS NOT"
        " NULL"
    )
    assert snapshot == sorted(row[0] for row in sql_cursor.fetchall())


def test_run_db_create__zids(
    sql_cursor: sqlite3.Cursor, snapshot: Snapshot
) -> None:
    """Check what create dates are indexed by running 'zorg db create'."""
    sql_cursor.execute("SELECT DISTINCT zid FROM zorgnote")
    assert snapshot == sorted(
        row[0] for row in sql_cursor.fetchall() if row[0]
    )
