"""Tests for IngestGateway and push_event flow."""

from __future__ import annotations

from datetime import datetime

from syke.ingestion.gateway import IngestGateway


def test_push_event_basic(db, user_id):
    """Push a single event via gateway, verify it's in the DB."""
    gw = IngestGateway(db, user_id)
    result = gw.push(
        source="test",
        event_type="note",
        title="Hello world",
        content="This is a test event pushed through the gateway.",
    )
    assert result["status"] == "ok"
    assert result["duplicate"] is False
    assert "event_id" in result

    # Verify in DB
    events = db.get_events(user_id, source="test")
    assert len(events) == 1
    assert events[0]["title"] == "Hello world"


def test_push_event_content_filter(db, user_id):
    """Push event with credentials — they should be sanitized."""
    gw = IngestGateway(db, user_id)
    # Use a Bearer token pattern that the content filter will catch and redact
    result = gw.push(
        source="test",
        event_type="note",
        title="Secret stuff",
        content="My token is Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.longtoken and that should be stripped.",
    )
    assert result["status"] == "ok"

    events = db.get_events(user_id, source="test")
    assert len(events) == 1
    # Credentials should be redacted
    assert "eyJhbGciOiJ" not in events[0]["content"]
    assert "[REDACTED]" in events[0]["content"]


def test_push_event_dedup_external_id(db, user_id):
    """Push same external_id twice — second should be a duplicate."""
    gw = IngestGateway(db, user_id)

    result1 = gw.push(
        source="test",
        event_type="note",
        title="First push",
        content="Content for dedup test.",
        external_id="ext-123",
    )
    assert result1["status"] == "ok"

    result2 = gw.push(
        source="test",
        event_type="note",
        title="Second push",
        content="Different content but same external_id.",
        external_id="ext-123",
    )
    assert result2["status"] == "duplicate"
    assert result2["duplicate"] is True

    # Only one event in DB
    assert db.count_events(user_id) == 1


def test_push_event_dedup_natural_key(db, user_id):
    """Push same (source, user, timestamp, title) twice — second is duplicate via DB constraint."""
    gw = IngestGateway(db, user_id)
    ts = "2025-06-15T10:00:00"

    result1 = gw.push(
        source="test",
        event_type="note",
        title="Same title",
        content="First version of content.",
        timestamp=ts,
    )
    assert result1["status"] == "ok"

    result2 = gw.push(
        source="test",
        event_type="note",
        title="Same title",
        content="Second version of content.",
        timestamp=ts,
    )
    assert result2["status"] == "duplicate"

    assert db.count_events(user_id) == 1


def test_push_batch(db, user_id):
    """Push array of events, verify counts."""
    gw = IngestGateway(db, user_id)
    events = [
        {"source": "test", "event_type": "note", "title": f"Batch {i}", "content": f"Batch content {i}"}
        for i in range(5)
    ]
    result = gw.push_batch(events)

    assert result["status"] == "ok"
    assert result["inserted"] == 5
    assert result["duplicates"] == 0
    assert result["filtered"] == 0
    assert result["total"] == 5

    assert db.count_events(user_id) == 5


def test_push_event_missing_fields(db, user_id):
    """Missing required fields should return an error."""
    gw = IngestGateway(db, user_id)

    # Missing content
    result = gw.push(source="test", event_type="note", title="No content", content="")
    assert result["status"] == "error"

    # Missing source
    result = gw.push(source="", event_type="note", title="No source", content="Some content")
    assert result["status"] == "error"

    # Missing event_type
    result = gw.push(source="test", event_type="", title="No type", content="Some content")
    assert result["status"] == "error"


def test_push_event_with_metadata(db, user_id):
    """Push event with metadata dict — should be stored correctly."""
    gw = IngestGateway(db, user_id)
    result = gw.push(
        source="test",
        event_type="observation",
        title="With metadata",
        content="Event that has metadata attached.",
        metadata={"mood": "curious", "confidence": 0.9},
    )
    assert result["status"] == "ok"

    events = db.get_events(user_id, source="test")
    assert len(events) == 1


def test_push_event_with_timestamp(db, user_id):
    """Push event with explicit ISO timestamp."""
    gw = IngestGateway(db, user_id)
    result = gw.push(
        source="test",
        event_type="note",
        title="Backdated",
        content="Event from the past.",
        timestamp="2024-01-15T09:30:00",
    )
    assert result["status"] == "ok"

    events = db.get_events(user_id, source="test")
    assert len(events) == 1
    assert "2024-01-15" in events[0]["timestamp"]
