# #region Test.Models.AuthLlm [C:1] [TYPE Module] [SEMANTICS test,models,auth,llm,generate_uuid]
# @BRIEF Tests for generate_uuid functions in auth.py and llm.py, and model column attributes.
# @RELATION BINDS_TO -> [AuthModels]
# @RELATION BINDS_TO -> [LlmModels]

import pytest


class TestAuthGenerateUuid:
    """generate_uuid in auth.py — UUID generation for primary keys."""

    def test_returns_string(self):
        from src.models.auth import generate_uuid

        uid = generate_uuid()
        assert isinstance(uid, str)
        assert len(uid) > 20

    def test_unique_values(self):
        from src.models.auth import generate_uuid

        uids = {generate_uuid() for _ in range(100)}
        assert len(uids) == 100


class TestAuthModelColumnAttrs:
    """Verify auth model column attributes.
    Note: SQLAlchemy Column(default=...) is INSERT-time only, not Python __init__ time.
    So we must pass all values explicitly.
    """

    def test_user_columns(self):
        from src.models.auth import User

        user = User(
            id="u-1", username="test_user",
            auth_source="LOCAL", is_active=True, is_ad_user=False,
        )
        assert user.id == "u-1"
        assert user.username == "test_user"
        assert user.auth_source == "LOCAL"
        assert user.is_active is True
        assert user.is_ad_user is False
        assert user.email is None
        assert user.password_hash is None
        assert user.full_name is None

    def test_user_with_all_fields(self):
        from src.models.auth import User

        user = User(
            id="u-2", username="admin", email="admin@example.com",
            password_hash="hash", full_name="Admin User",
            auth_source="ADFS", is_active=True, is_ad_user=True,
        )
        assert user.email == "admin@example.com"
        assert user.password_hash == "hash"
        assert user.full_name == "Admin User"
        assert user.auth_source == "ADFS"
        assert user.is_ad_user is True

    def test_role_columns(self):
        from src.models.auth import Role

        role = Role(id="r-1", name="test_role", is_admin=False)
        assert role.id == "r-1"
        assert role.name == "test_role"
        assert role.is_admin is False

    def test_role_admin(self):
        from src.models.auth import Role

        role = Role(id="r-2", name="admin", is_admin=True)
        assert role.is_admin is True

    def test_permission_columns(self):
        from src.models.auth import Permission

        perm = Permission(id="p-1", resource="dashboard", action="READ")
        assert perm.id == "p-1"
        assert perm.resource == "dashboard"
        assert perm.action == "READ"

    def test_ad_group_mapping_columns(self):
        from src.models.auth import ADGroupMapping

        mapping = ADGroupMapping(id="m-1", ad_group="DOMAIN\\Users", role_id="role-1")
        assert mapping.id == "m-1"
        assert mapping.ad_group == "DOMAIN\\Users"
        assert mapping.role_id == "role-1"

    def test_token_blacklist_columns(self):
        from datetime import datetime
        from src.models.auth import TokenBlacklist

        ts = datetime.now()
        tb = TokenBlacklist(
            jti="jti-1", token_hash="a" * 64, expires_at=ts,
            revoked_at=ts,
        )
        assert tb.jti == "jti-1"
        assert tb.token_hash == "a" * 64
        assert tb.expires_at == ts
        assert tb.revoked_at is not None


class TestLlmGenerateUuid:
    """generate_uuid in llm.py."""

    def test_returns_string(self):
        from src.models.llm import generate_uuid

        uid = generate_uuid()
        assert isinstance(uid, str)
        assert len(uid) > 20

    def test_unique_values(self):
        from src.models.llm import generate_uuid

        uids = {generate_uuid() for _ in range(50)}
        assert len(uids) == 50


class TestLlmModelColumnAttrs:
    """Verify LLM model column attributes with explicit values."""

    def test_llm_provider_columns(self):
        from src.models.llm import LLMProvider

        provider = LLMProvider(
            id="lp-1", provider_type="openai", name="GPT-4",
            base_url="https://api.openai.com", api_key="sk-xxx",
            default_model="gpt-4", is_active=True, is_multimodal=False,
        )
        assert provider.id == "lp-1"
        assert provider.is_active is True
        assert provider.is_multimodal is False

    def test_llm_provider_multimodal(self):
        from src.models.llm import LLMProvider

        provider = LLMProvider(
            id="lp-2", provider_type="openai", name="GPT-4V",
            base_url="https://api.openai.com", api_key="sk-xxx",
            default_model="gpt-4-vision", is_active=True, is_multimodal=True,
            max_images=10, context_window=128000, max_output_tokens=4096,
        )
        assert provider.is_multimodal is True
        assert provider.max_images == 10
        assert provider.context_window == 128000
        assert provider.max_output_tokens == 4096

    def test_validation_policy_columns(self):
        from datetime import time
        from src.models.llm import ValidationPolicy

        policy = ValidationPolicy(
            id="vp-1", name="Test Policy", environment_id="env-1",
            dashboard_ids=["1", "2"], schedule_days=[1, 3, 5],
            window_start=time(9, 0), window_end=time(18, 0),
            is_active=True, screenshot_enabled=True, logs_enabled=True,
            execute_chart_data=False, llm_batch_size=1,
            policy_dashboard_concurrency_limit=3, notify_owners=True,
            alert_condition="FAIL_ONLY",
        )
        assert policy.id == "vp-1"
        assert policy.is_active is True
        assert policy.screenshot_enabled is True
        assert policy.logs_enabled is True
        assert policy.execute_chart_data is False
        assert policy.llm_batch_size == 1

    def test_validation_policy_v2_fields(self):
        from datetime import time
        from src.models.llm import ValidationPolicy

        policy = ValidationPolicy(
            id="vp-2", name="V2 Policy", environment_id="env-2",
            dashboard_ids=[], schedule_days=[1, 3, 5],
            window_start=time(9, 0), window_end=time(18, 0),
            prompt_template="Custom template",
            screenshot_enabled=False, logs_enabled=False,
            execute_chart_data=True, llm_batch_size=5,
            policy_dashboard_concurrency_limit=10,
        )
        assert policy.prompt_template == "Custom template"
        assert policy.llm_batch_size == 5
        assert policy.policy_dashboard_concurrency_limit == 10

    def test_validation_source_columns(self):
        from src.models.llm import ValidationSource

        source = ValidationSource(
            id="vs-1", policy_id="pol-1", type="dashboard_id",
            value="42", status="valid",
        )
        assert source.id == "vs-1"
        assert source.status == "valid"

    def test_validation_source_invalid_status(self):
        from src.models.llm import ValidationSource

        source = ValidationSource(
            id="vs-2", policy_id="pol-1", type="dashboard_url",
            value="http://superset/dash/42",
            status="parse_failed", last_error="Could not parse URL",
            title="Sales Dashboard",
            resolved_dashboard_id="42",
        )
        assert source.status == "parse_failed"
        assert source.last_error == "Could not parse URL"
        assert source.title == "Sales Dashboard"

    def test_validation_record_columns(self):
        from src.models.llm import ValidationRecord

        record = ValidationRecord(
            id="vr-1", dashboard_id="42", environment_id="env-1",
            status="PASS", summary="All good", issues=[],
        )
        assert record.id == "vr-1"
        assert record.issues == []
        assert record.task_id is None

    def test_validation_record_with_issues(self):
        from src.models.llm import ValidationRecord

        record = ValidationRecord(
            id="vr-2", dashboard_id="99", environment_id="env-1",
            status="FAIL", summary="Errors found",
            issues=[{"severity": "FAIL", "message": "Chart broken"}],
            screenshot_path="/screens/1.png",
            raw_response='{"ok": false}',
        )
        assert len(record.issues) == 1
        assert record.screenshot_path == "/screens/1.png"

    def test_validation_run_columns(self):
        from src.models.llm import ValidationRun

        run = ValidationRun(
            id="vrun-1", policy_id="pol-1",
            trigger="manual", status="running",
            dashboard_count=0,
        )
        assert run.id == "vrun-1"
        assert run.trigger == "manual"
        assert run.status == "running"
        assert run.dashboard_count == 0

    def test_validation_run_scheduled(self):
        from src.models.llm import ValidationRun

        run = ValidationRun(
            id="vrun-2", policy_id="pol-1",
            trigger="scheduled", status="completed",
            dashboard_count=5, pass_count=4, fail_count=1,
            warn_count=0, unknown_count=0,
        )
        assert run.trigger == "scheduled"
        assert run.dashboard_count == 5
        assert run.pass_count == 4
# #endregion Test.Models.AuthLlm
