import pytest

from goodnews import queries
from goodnews.db import connect, init_db


@pytest.fixture
def conn():
    c = connect(":memory:")
    init_db(c)
    c.execute("INSERT INTO sources (id, name, feed_url, trust_score) VALUES (1,'S','http://s/f',5)")
    rows = [
        (1, "science", "discovery", 1),
        (2, "animals", "discovery", 1),
        (3, "health", "breakthrough", 2),
        (4, "community", "solution", 1),
        (5, "environment", "solution", 7),  # high cortisol
    ]
    for aid, topic, flavor, cort in rows:
        c.execute(
            "INSERT INTO articles (id, source_id, canonical_url, title, url_hash) VALUES (?,1,?,?,?)",
            (aid, f"http://s/{aid}", f"t{aid}", f"h{aid}"),
        )
        c.execute(
            "INSERT INTO article_scores (article_id, constructive_score, agency_score, human_benefit_score, "
            "cortisol_score, ragebait_score, pr_risk_score, accepted, topic, flavor) "
            "VALUES (?, 6, 2, 2, ?, 0, 2, 1, ?, ?)",
            (aid, cort, topic, flavor),
        )
    c.commit()
    yield c
    c.close()


def _topics(rows):
    return sorted({r["topic"] for r in rows})


def test_include_topics_in_sql(conn):
    rows = queries.feed(conn, include_topics=["science", "animals"], limit=50)
    assert _topics(rows) == ["animals", "science"]


def test_include_flavors_in_sql(conn):
    rows = queries.feed(conn, include_flavors=["discovery"], limit=50)
    assert sorted({r["flavor"] for r in rows}) == ["discovery"]


def test_include_topic_and_flavor_are_anded(conn):
    # Wonder-style: (science/animals/culture) AND discovery
    rows = queries.feed(conn, include_topics=["science", "animals", "culture"], include_flavors=["discovery"], limit=50)
    assert _topics(rows) == ["animals", "science"]  # the two discovery items


def test_mute_topics_excludes(conn):
    rows = queries.feed(conn, mute_topics=["health", "environment"], limit=50)
    assert "health" not in _topics(rows) and "environment" not in _topics(rows)


def test_max_cortisol_ceiling(conn):
    rows = queries.feed(conn, max_cortisol=2, limit=50)
    assert all((r["cortisol_score"] or 0) <= 2 for r in rows)
    assert "environment" not in _topics(rows)  # the cortisol=7 item is gone


def test_duplicates_excluded(conn):
    conn.execute("UPDATE articles SET duplicate_of = 1 WHERE id = 2")
    conn.commit()
    ids = {r["id"] for r in queries.feed(conn, limit=50)}
    assert 2 not in ids
