# #region Test.SupersetContextTemplatesExtra [C:2] [TYPE Module] [SEMANTICS test, superset, template, edge]
# @BRIEF Extra tests for _templates.py — edge cases covering lines 45, 62, 80, 92, 148.
# @RELATION BINDS_TO -> [SupersetContextTemplatesMixin]

from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))

import os

os.environ.setdefault("SECRET_KEY", "test-secret-key-for-testing")
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("AUTH_DATABASE_URL", "sqlite:///:memory:")

import pytest

from src.core.utils.superset_context_extractor._templates import (
    SupersetContextTemplatesMixin,
)


class _TestExtractor(SupersetContextTemplatesMixin):
    """Concrete test class for the mixin."""
    pass


@pytest.fixture
def extractor():
    return _TestExtractor()


class TestDiscoverTemplateVariablesExtra:
    """Extra edge cases for discover_template_variables."""

    def test_empty_filter_values_variable_skipped(self, extractor):
        """filter_values('') with empty name is skipped (line 45)."""
        result = extractor.discover_template_variables({
            "sql": "{{ filter_values('') }}"
        })
        assert result == []

    def test_empty_url_param_variable_skipped(self, extractor):
        """url_param('') with empty name is skipped (line 62)."""
        result = extractor.discover_template_variables({
            "sql": "{{ url_param('') }}"
        })
        assert result == []

    def test_empty_jinja_expression_skipped(self, extractor):
        """Empty Jinja expression {{ }} is skipped (line 80)."""
        result = extractor.discover_template_variables({
            "sql": "SELECT * FROM table WHERE {{  }}"
        })
        assert result == []

    def test_jinja_keyword_not_identifier(self, extractor):
        """Jinja expression with 'if' keyword returns no variable (line 92)."""
        result = extractor.discover_template_variables({
            "sql": "{% if True %} SELECT * FROM table {% endif %}"
        })
        # The {% %} block is not matched by {{ }} re pattern, so this is fine.
        # Test with {{ if }} instead:
        result = extractor.discover_template_variables({
            "sql": "SELECT * FROM table WHERE {{ if }}"
        })
        assert result == []

    def test_non_dict_column_skipped_in_columns(self, extractor):
        """Non-dict item in columns list is skipped (line 148)."""
        result = extractor._collect_query_bearing_expressions({
            "columns": [
                "string_column",
                {"sqlExpression": "UPPER(name)"},
                42,
            ]
        })
        assert "UPPER(name)" in result
        # string items and non-dict int items should not appear
        assert "string_column" not in result  # it's a str but append_expression checks type

    def test_jinja_expression_with_dot_skip(self, extractor):
        """Jinja expression using filter_values inside {{ }} is skipped."""
        result = extractor.discover_template_variables({
            "sql": "{{ filter_values('country') }}"
        })
        # filter_values inside {{ }} is already caught by the filter_values regex,
        # and the jinja_match also matches but is skipped due to token check.
        # Should get one entry from filter_values match.
        assert len(result) == 1
        assert result[0]["variable_kind"] == "native_filter"

    def test_jinja_expression_with_get_filters_skipped(self, extractor):
        """Jinja expression with get_filters is skipped (no extra entry)."""
        result = extractor.discover_template_variables({
            "sql": "{{ get_filters('country') }}"
        })
        # get_filters is not in the filter_values regex, but jinja_match captures it.
        # It has 'get_filters(' so the inner loop skips it.
        assert result == []

    def test_url_param_with_default_value(self, extractor):
        """url_param with default literal parsed correctly."""
        result = extractor.discover_template_variables({
            "sql": "{{ url_param('limit', '100') }}"
        })
        param = next(v for v in result if v["variable_name"] == "limit")
        assert param["is_required"] is False
        assert param["default_value"] == "100"
# #endregion Test.SupersetContextTemplatesExtra
