from datetime import datetime


def test_create_new_alert_when_none_exists(client, mock_db):
    # First fetchone(): checks for an existing pending alert in the last
    # 60 seconds -> simulate "not found"
    # Second fetchone(): returns (id, created_at) of the newly inserted row
    mock_db.fetchone.side_effect = [
        None,
        (1, datetime.now())
    ]

    response = client.post("/api/alerts", json={
        "attack_type": "DDoS",
        "src_ip": "185.220.101.5",
        "severity": "HIGH"
    })

    assert response.status_code == 200
    body = response.json()
    assert body["status"] == "saved"
    assert body["data"]["attack_type"] == "DDoS"


def test_repeated_alert_within_60s_increments_occurrence_count(client, mock_db):
    # Simulate an existing pending alert for the same src_ip/attack_type
    # already seen 3 times
    mock_db.fetchone.side_effect = [
        (7, 3),                # existing alert found: (id, occurrence_count)
        (7, datetime.now())    # UPDATE ... RETURNING id, created_at
    ]

    response = client.post("/api/alerts", json={
        "attack_type": "Brute-Force",
        "src_ip": "10.0.0.99",
        "severity": "MEDIUM"
    })

    assert response.status_code == 200
    body = response.json()
    assert body["status"] == "updated"
    assert body["occurrence_count"] == 4   # 3 + 1


def test_create_alert_missing_required_field_rejected(client):
    response = client.post("/api/alerts", json={
        "attack_type": "DDoS"
        # src_ip and severity missing on purpose
    })
    assert response.status_code == 422


def test_get_alerts_returns_expected_structure(client, mock_db):
    mock_db.fetchall.return_value = [
        (1, "DDoS", "185.220.101.5", "HIGH",
         "2026-07-27 10:00:00", "2026-07-27 10:00:00", "pending", 1)
    ]

    response = client.get("/api/alerts")

    assert response.status_code == 200
    body = response.json()
    assert body["count"] == 1
    assert body["alerts"][0]["occurrence_count"] == 1
