"""Tests for Cypher → SQL translation."""

import pytest

from piggie._cypher.parser import extract_return_columns
from piggie._cypher.wrapper import build_cypher_sql


class TestExtractReturnColumns:
    def test_single_variable(self):
        assert extract_return_columns("MATCH (n) RETURN n") == ["n"]

    def test_dotted_properties(self):
        cols = extract_return_columns("MATCH (n:Person) RETURN n.name, n.age")
        assert cols == ["name", "age"]

    def test_as_alias(self):
        cols = extract_return_columns("MATCH (n) RETURN n.name AS person_name")
        assert cols == ["person_name"]

    def test_function_call(self):
        cols = extract_return_columns("MATCH (n) RETURN count(n)")
        assert cols == ["count"]

    def test_function_with_alias(self):
        cols = extract_return_columns("MATCH (n) RETURN count(n) AS total")
        assert cols == ["total"]

    def test_star(self):
        cols = extract_return_columns("MATCH (n) RETURN *")
        assert cols == ["v"]

    def test_mixed(self):
        cols = extract_return_columns(
            "MATCH (n:Person)-[r:KNOWS]->(m) "
            "RETURN n.name AS source, m.name AS target, r.since"
        )
        assert cols == ["source", "target", "since"]

    def test_with_order_by(self):
        cols = extract_return_columns(
            "MATCH (n) RETURN n.name, n.age ORDER BY n.age"
        )
        assert cols == ["name", "age"]

    def test_with_limit(self):
        cols = extract_return_columns(
            "MATCH (n) RETURN n.name LIMIT 10"
        )
        assert cols == ["name"]

    def test_return_distinct(self):
        cols = extract_return_columns(
            "MATCH (n) RETURN DISTINCT n.name"
        )
        assert cols == ["name"]

    def test_no_return_defaults_to_v(self):
        # Write-only queries get a default single column
        cols = extract_return_columns("MATCH (n) SET n.x = 1")
        assert cols == ["v"]

    def test_nested_function(self):
        cols = extract_return_columns(
            "MATCH (n) RETURN collect(n.name) AS names"
        )
        assert cols == ["names"]


class TestBuildCypherSql:
    def test_single_column(self):
        stmt = build_cypher_sql(["v"])
        assert stmt == "SELECT * FROM cypher(NULL,NULL) AS (v agtype);"

    def test_multiple_columns(self):
        stmt = build_cypher_sql(["name", "age"])
        assert stmt == "SELECT * FROM cypher(NULL,NULL) AS (name agtype,age agtype);"

    def test_invalid_column_name(self):
        with pytest.raises(ValueError, match="Invalid column name"):
            build_cypher_sql(["bad name"])

    def test_injection_attempt(self):
        with pytest.raises(ValueError):
            build_cypher_sql(["'; DROP TABLE users; --"])
