# #region Test.SqlTableExtractor.Coverage [C:2] [TYPE Module] [SEMANTICS test, sql, table, extractor, coverage, edge, dead-code]
# @BRIEF Edge coverage for sql_table_extractor.py uncovered lines:
#   Line 157: walk_tokens recursion for TokenList
#   Line 169: stmt is None continue guard
# @RELATION BINDS_TO -> [SqlTableExtractorModule]

from unittest.mock import MagicMock, patch
import pytest
from sqlparse.sql import TokenList


class FakeTokenList(TokenList):
    """Minimal TokenList subclass that avoids sqlparse internal setup."""
    def __init__(self):
        self.ttype = None
        self._groupable = True
        self.tokens = []

    def flatten(self):
        return iter(self.tokens)


class TestExtractTablesFromSqlSpanCoverage:
    """Cover dead-code paths in extract_tables_from_sql_span."""

    # Line 169: stmt is None → continue
    # sqlparse.parse never returns None elements in practice, but code guards against it.
    # Must use SQL with schema.table match to get past the early return (line 146).
    def test_sqlparse_parse_returns_none_skipped(self):
        """sqlparse.parse returns [None] → stmt is None skipped (line 169)."""
        with patch("src.services.sql_table_extractor.sqlparse.parse", return_value=[None]):
            from src.services.sql_table_extractor import extract_tables_from_sql_span
            # Must have schema.table match to get past line 146
            result = extract_tables_from_sql_span("SELECT * FROM raw.sales")
            # With no walk_tokens output, regex matches are not filtered by string check
            assert "raw.sales" in result

    # Line 157: walk_tokens(token.flatten(), offset) — TokenList recursion
    # Normally walk_tokens is called with stmt.flatten() which yields only leaf tokens.
    # This test forces a TokenList into the flattened output to exercise the recursive path.
    def test_walk_tokens_tokenlist_recursion(self):
        """TokenList in flattened output → recursive walk_tokens call (line 157)."""
        # Use a concrete TokenList subclass
        fake_tl = FakeTokenList()

        # Create a mock statement whose flatten() yields the TokenList
        stmt_mock = MagicMock()
        stmt_mock.flatten.return_value = [fake_tl]

        with patch("src.services.sql_table_extractor.sqlparse.parse", return_value=[stmt_mock]):
            from src.services.sql_table_extractor import extract_tables_from_sql_span
            # Must have schema.table match to get past line 146
            result = extract_tables_from_sql_span("SELECT * FROM raw.sales")
            # No string literal ranges → raw.sales should be in result
            assert "raw.sales" in result
# #endregion Test.SqlTableExtractor.Coverage
