"""
Tests for urlink client
"""

import pytest
from urlink.client import (
    UrlinkClient,
    UrlinkValidationError,
    UrlinkAPIError,
)


class TestUrlinkClient:
    """Test cases for UrlinkClient class."""
    
    def test_client_initialization(self):
        """Test client initializes with default values."""
        client = UrlinkClient()
        assert client.base_url == "https://urlink.co"
        assert client.api_key is None
        assert client.timeout == 30
    
    def test_client_custom_config(self):
        """Test client accepts custom configuration."""
        client = UrlinkClient(
            api_key="test-key",
            base_url="https://custom.domain.com",
            timeout=60
        )
        assert client.base_url == "https://custom.domain.com"
        assert client.api_key == "test-key"
        assert client.timeout == 60
    
    def test_base_url_trailing_slash_removed(self):
        """Test trailing slash is removed from base URL."""
        client = UrlinkClient(base_url="https://example.com/")
        assert client.base_url == "https://example.com"
    
    def test_shorten_validation_empty_url(self):
        """Test validation error for empty URL."""
        client = UrlinkClient()
        with pytest.raises(UrlinkValidationError) as exc_info:
            client.shorten("")
        assert "URL is required" in str(exc_info.value)
    
    def test_shorten_validation_invalid_protocol(self):
        """Test validation error for invalid protocol."""
        client = UrlinkClient()
        with pytest.raises(UrlinkValidationError) as exc_info:
            client.shorten("ftp://example.com")
        assert "http://" in str(exc_info.value)
    
    def test_shorten_validation_invalid_code_too_short(self):
        """Test validation error for code that's too short."""
        client = UrlinkClient()
        with pytest.raises(UrlinkValidationError) as exc_info:
            client.shorten("https://example.com", code="ab")
        assert "3-48 characters" in str(exc_info.value)
    
    def test_shorten_validation_invalid_code_chars(self):
        """Test validation error for code with invalid characters."""
        client = UrlinkClient()
        with pytest.raises(UrlinkValidationError) as exc_info:
            client.shorten("https://example.com", code="abc@#$")
        assert "letters, numbers, dashes" in str(exc_info.value)
    
    def test_shorten_validation_valid_code(self):
        """Test valid code formats don't raise validation error."""
        client = UrlinkClient(api_key="test-key")
        # These should not raise validation errors (they may fail on API call)
        valid_codes = [
            "abc",
            "my-link",
            "my_link",
            "MyLink123",
            "a" * 48,  # max length
        ]
        for code in valid_codes:
            try:
                client.shorten("https://example.com", code=code)
            except UrlinkValidationError:
                pytest.fail(f"Valid code '{code}' raised validation error")
            except UrlinkAPIError:
                pass  # API error is expected since we're not mocking
            except Exception:
                pass  # Connection error is expected
    
    def test_check_availability_empty_code(self):
        """Test validation error for empty code."""
        client = UrlinkClient()
        with pytest.raises(UrlinkValidationError) as exc_info:
            client.check_availability("")
        assert "Code is required" in str(exc_info.value)


class TestBulkShorten:
    """Test cases for bulk shortening."""
    
    def test_bulk_shorten_empty_list(self):
        """Test bulk shorten with empty list."""
        client = UrlinkClient(api_key="test-key")
        results = client.bulk_shorten([])
        assert results == []
    
    def test_bulk_shorten_handles_errors(self):
        """Test bulk shorten handles individual errors gracefully."""
        client = UrlinkClient(api_key="test-key")
        urls = [
            "invalid-url",  # Should fail validation
            "https://example.com",  # Valid but may fail API
        ]
        results = client.bulk_shorten(urls)
        
        assert len(results) == 2
        assert results[0]['success'] is False
        assert 'error' in results[0]
