"""
Tests for enhanced company_to_domain transform.
"""
import os
import pytest
from src.fmatch.saas.operators.company_to_domain import company_to_domain


class TestCompanyToDomainEnhanced:
    """Test the enhanced waterfall strategy for company-to-domain conversion."""

    def test_registry_lookup(self):
        """Test that registry lookups work for known companies."""
        # This requires the domain family registry to be available
        # Accenture should be in the registry based on the sample data
        result = company_to_domain("Accenture", use_registry=True)

        assert result["value"]["domain"]
        assert result["value"]["confidence"] in ["high", "medium", "low"]

        # If registry hit, should be high confidence with source
        if result["value"].get("source") == "registry":
            assert result["value"]["confidence"] == "high"
            assert "family_id" in result["value"]

    def test_hardcoded_fallback(self):
        """Test hardcoded dictionary fallback."""
        result = company_to_domain("Google", use_registry=False)

        assert result["value"]["domain"] == "google.com"
        assert result["value"]["confidence"] == "high"
        assert result["value"].get("source") == "hardcoded"

    def test_heuristic_fallback(self):
        """Test heuristic TLD guessing for unknown companies."""
        # Disable registry to force heuristics
        result = company_to_domain("Acme Widgets Corp", use_registry=False)

        # Should generate acmewidgetscorp.com or similar
        assert result["value"]["domain"]
        assert ".com" in result["value"]["domain"]
        assert result["value"]["confidence"] in ["low", "medium"]
        assert result["value"].get("source") == "heuristic"

    def test_edu_heuristic(self):
        """Test .edu heuristic for universities."""
        result = company_to_domain("Stanford University", use_registry=False)

        assert result["value"]["domain"]
        assert ".edu" in result["value"]["domain"]
        assert result["value"]["confidence"] == "medium"

    def test_org_heuristic(self):
        """Test .org heuristic for nonprofits."""
        result = company_to_domain("Red Cross Foundation", use_registry=False)

        assert result["value"]["domain"]
        assert ".org" in result["value"]["domain"]
        assert result["value"]["confidence"] == "medium"

    def test_uk_heuristic(self):
        """Test .co.uk heuristic for UK companies."""
        result = company_to_domain("London Software Ltd UK", use_registry=False)

        assert result["value"]["domain"]
        assert ".co.uk" in result["value"]["domain"]
        assert result["value"]["confidence"] == "medium"

    def test_empty_input(self):
        """Test handling of empty input."""
        result = company_to_domain("")

        assert result["value"]["domain"] == ""
        assert result["value"]["confidence"] == "low"

    def test_wikidata_lookup(self):
        """Test Wikidata index lookup if available."""
        # This test will pass if Wikidata index exists, skip otherwise
        wikidata_path = os.getenv("WIKIDATA_INDEX_PATH", "config/wikidata_companies.duckdb")

        if not os.path.exists(wikidata_path):
            pytest.skip("Wikidata index not built")

        # Try a well-known company
        result = company_to_domain("Microsoft", use_registry=False)

        # Should hit either hardcoded or Wikidata
        if result["value"].get("source") == "wikidata":
            assert result["value"]["domain"]
            assert result["value"]["confidence"] == "high"

    def test_dns_validation(self):
        """Test DNS validation if dnspython is available."""
        try:
            import dns.resolver
        except ImportError:
            pytest.skip("dnspython not installed")

        # Test with a real company that should have DNS
        result = company_to_domain("Salesforce", use_registry=False, use_dns=True)

        # Should validate salesforce.com exists
        assert result["value"]["domain"]

    def test_llm_fallback(self):
        """Test LLM fallback if Ollama is available."""
        llm_enabled = os.getenv("FM_COMPANY_TO_DOMAIN_LLM", "false").lower() == "true"

        if not llm_enabled:
            pytest.skip("LLM not enabled")

        result = company_to_domain("Anthropic", use_registry=False, use_dns=False, use_llm=True)

        # LLM should predict something
        assert result["value"]["domain"]
        if result["value"].get("source") == "llm":
            assert result["value"]["confidence"] in ["medium", "high"]


class TestV1Guardrails:
    """Test v1 guardrails enforcement for Google Sheets."""

    def test_v1_skips_wikidata(self):
        """Test that v1 mode skips Wikidata lookups for performance."""
        # Use a company that's NOT in registry but IS in Wikidata
        # Set env to enable Wikidata globally
        os.environ["FM_COMPANY_TO_DOMAIN_WIKIDATA"] = "true"

        # Call with default v1 mode (use_wikidata=False is enforced)
        result = company_to_domain("Random Fake Company XYZ123")

        # Should NOT hit Wikidata, should return empty for non-registry companies
        assert result["value"]["domain"] == ""
        assert result["value"]["confidence"] <= 0.60  # Below threshold
        # Check that the reason indicates it's not in registry
        if "meta" in result:
            assert result["meta"].get("reason") == "confidence_below_threshold"

    def test_v1_skips_heuristics(self):
        """Test that v1 mode skips heuristic candidate generation."""
        # Use a company not in registry or hardcoded
        result = company_to_domain("Fictional Startup ABC Corp")

        # V1 mode should return empty, not generate heuristic candidates
        assert result["value"]["domain"] == ""
        assert result["value"]["confidence"] <= 0.60

        # The underlying source should be 'none' not 'heuristic'
        # (confidence filter hides this, but we can check it doesn't do DNS/heuristics)
        # If confidence is 0, it means it didn't even try heuristics

    def test_v1_allows_registry_hits(self):
        """Test that v1 mode still allows registry hits."""
        # Google is in hardcoded dict
        result = company_to_domain("Google")

        # Should succeed from hardcoded/registry
        assert result["value"]["domain"] == "google.com"
        assert result["value"]["confidence"] >= 0.60

    def test_batch_honors_v1_guardrails(self):
        """Test that batch processing honors v1 guardrails."""
        from src.fmatch.saas.operators.company_to_domain import resolve_company_to_domain_batch

        # Mix of registry and non-registry companies
        names = ["Google", "Fictional XYZ Corp", "Microsoft"]
        result = resolve_company_to_domain_batch(names)

        values = result["values"]
        assert len(values) == 3

        # Google should succeed (hardcoded)
        assert values[0]["value"]["domain"]

        # Fictional should be empty (not in registry, v1 skips heuristics)
        assert values[1]["value"]["domain"] == ""

        # Microsoft should succeed (hardcoded)
        assert values[2]["value"]["domain"]


class TestDomainValidators:
    """Test domain candidate generation and validation."""

    def test_generate_candidates(self):
        """Test domain candidate generation."""
        from src.fmatch.saas.operators.domain_validators import generate_domain_candidates

        candidates = generate_domain_candidates("Acme Corp")

        assert len(candidates) > 0
        assert "acme.com" in candidates or "acmecorp.com" in candidates

    def test_generate_uk_candidates(self):
        """Test UK domain candidate generation."""
        from src.fmatch.saas.operators.domain_validators import generate_domain_candidates

        candidates = generate_domain_candidates("UK Software Ltd")

        # Should include .co.uk
        assert any(".co.uk" in c for c in candidates)

    def test_validate_dns_real_domain(self):
        """Test DNS validation with a real domain."""
        from src.fmatch.saas.operators.domain_validators import validate_domain_dns

        try:
            import dns.resolver
        except ImportError:
            pytest.skip("dnspython not installed")

        # Test with google.com (very likely to have DNS)
        result = validate_domain_dns("google.com")
        assert result is True

    def test_validate_dns_fake_domain(self):
        """Test DNS validation with a fake domain."""
        from src.fmatch.saas.operators.domain_validators import validate_domain_dns

        try:
            import dns.resolver
        except ImportError:
            pytest.skip("dnspython not installed")

        # Test with a domain that should not exist
        result = validate_domain_dns("this-domain-definitely-does-not-exist-12345.com")
        assert result is False


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
