"""Tests for constants module.

This module contains tests for the constants defined in the library,
including API URLs, AWS Cognito configuration, and HTTP headers.
"""

from __future__ import annotations

import logging

from aiokwikset.const import (
    ACCESSORY_COMMAND_URL,
    API_BASE_URL,
    CLIENT_ID,
    DEFAULT_HEADER_ACCEPT_ENCODING,
    DEFAULT_HEADER_USER_AGENT,
    GET_DEVICE_URL,
    GET_HOME_DEVICES_URL,
    GET_HOMES_URL,
    GET_USER_URL,
    LOCK_COMMAND_URL,
    LOGGER,
    LOGIN_HEADER_USER_AGENT,
    POOL_ID,
    POOL_REGION,
)

# ============================================================================
# AWS Cognito Configuration Tests
# ============================================================================


class TestCognitoConfig:
    """Tests for AWS Cognito configuration constants."""

    def test_pool_id_format(self) -> None:
        """Test POOL_ID has correct format."""
        assert POOL_ID is not None
        assert isinstance(POOL_ID, str)
        # Should be in format: region_poolid
        assert "_" in POOL_ID
        assert POOL_ID.startswith("us-east-1")

    def test_client_id_not_empty(self) -> None:
        """Test CLIENT_ID is not empty."""
        assert CLIENT_ID is not None
        assert isinstance(CLIENT_ID, str)
        assert len(CLIENT_ID) > 0

    def test_pool_region(self) -> None:
        """Test POOL_REGION is valid AWS region."""
        assert POOL_REGION is not None
        assert isinstance(POOL_REGION, str)
        # Should be a valid AWS region format
        assert POOL_REGION == "us-east-1"


# ============================================================================
# API URL Tests
# ============================================================================


class TestAPIURLs:
    """Tests for API URL constants."""

    def test_api_base_url(self) -> None:
        """Test API_BASE_URL is a valid HTTPS URL."""
        assert API_BASE_URL is not None
        assert API_BASE_URL.startswith("https://")
        assert "amazonaws.com" in API_BASE_URL

    def test_get_user_url(self) -> None:
        """Test GET_USER_URL is properly formatted."""
        assert GET_USER_URL is not None
        assert GET_USER_URL.startswith(API_BASE_URL)
        assert "users/me" in GET_USER_URL

    def test_get_homes_url(self) -> None:
        """Test GET_HOMES_URL is properly formatted."""
        assert GET_HOMES_URL is not None
        assert GET_HOMES_URL.startswith(API_BASE_URL)
        assert "users/me/homes" in GET_HOMES_URL

    def test_get_home_devices_url_has_placeholder(self) -> None:
        """Test GET_HOME_DEVICES_URL has home_id placeholder."""
        assert GET_HOME_DEVICES_URL is not None
        assert "%s" in GET_HOME_DEVICES_URL
        assert "homes" in GET_HOME_DEVICES_URL
        assert "devices" in GET_HOME_DEVICES_URL

    def test_get_device_url_has_placeholder(self) -> None:
        """Test GET_DEVICE_URL has device_id placeholder."""
        assert GET_DEVICE_URL is not None
        assert "%s" in GET_DEVICE_URL
        assert "devices" in GET_DEVICE_URL

    def test_lock_command_url_has_placeholder(self) -> None:
        """Test LOCK_COMMAND_URL has device_id placeholder."""
        assert LOCK_COMMAND_URL is not None
        assert "%s" in LOCK_COMMAND_URL
        assert "devices" in LOCK_COMMAND_URL
        assert "status" in LOCK_COMMAND_URL

    def test_accessory_command_url_has_placeholders(self) -> None:
        """Test ACCESSORY_COMMAND_URL has device and action placeholders."""
        assert ACCESSORY_COMMAND_URL is not None
        # Should have two placeholders: device_id and action
        assert ACCESSORY_COMMAND_URL.count("%s") == 2
        assert "devices" in ACCESSORY_COMMAND_URL


class TestURLFormatting:
    """Tests for URL string formatting."""

    def test_get_home_devices_url_formatting(self) -> None:
        """Test GET_HOME_DEVICES_URL can be formatted with home_id."""
        formatted = GET_HOME_DEVICES_URL % "home-123"

        assert "home-123" in formatted
        assert "%s" not in formatted

    def test_get_device_url_formatting(self) -> None:
        """Test GET_DEVICE_URL can be formatted with device_id."""
        formatted = GET_DEVICE_URL % "device-456"

        assert "device-456" in formatted
        assert "%s" not in formatted

    def test_lock_command_url_formatting(self) -> None:
        """Test LOCK_COMMAND_URL can be formatted with device_id."""
        formatted = LOCK_COMMAND_URL % "SN12345"

        assert "SN12345" in formatted
        assert "%s" not in formatted

    def test_accessory_command_url_formatting(self) -> None:
        """Test ACCESSORY_COMMAND_URL can be formatted with device and action."""
        formatted = ACCESSORY_COMMAND_URL % ("SN12345", "ledstatus")

        assert "SN12345" in formatted
        assert "ledstatus" in formatted
        assert "%s" not in formatted


# ============================================================================
# HTTP Header Tests
# ============================================================================


class TestHTTPHeaders:
    """Tests for HTTP header constants."""

    def test_login_header_user_agent(self) -> None:
        """Test LOGIN_HEADER_USER_AGENT is properly formatted."""
        assert LOGIN_HEADER_USER_AGENT is not None
        assert isinstance(LOGIN_HEADER_USER_AGENT, str)
        assert "aws-sdk" in LOGIN_HEADER_USER_AGENT.lower()

    def test_default_header_user_agent(self) -> None:
        """Test DEFAULT_HEADER_USER_AGENT is properly formatted."""
        assert DEFAULT_HEADER_USER_AGENT is not None
        assert isinstance(DEFAULT_HEADER_USER_AGENT, str)
        assert "okhttp" in DEFAULT_HEADER_USER_AGENT.lower()

    def test_default_header_accept_encoding(self) -> None:
        """Test DEFAULT_HEADER_ACCEPT_ENCODING is properly formatted."""
        assert DEFAULT_HEADER_ACCEPT_ENCODING is not None
        assert isinstance(DEFAULT_HEADER_ACCEPT_ENCODING, str)
        assert "gzip" in DEFAULT_HEADER_ACCEPT_ENCODING


# ============================================================================
# Logger Tests
# ============================================================================


class TestLogger:
    """Tests for logger configuration."""

    def test_logger_is_configured(self) -> None:
        """Test LOGGER is a properly configured Logger instance."""
        assert LOGGER is not None
        assert isinstance(LOGGER, logging.Logger)

    def test_logger_has_correct_name(self) -> None:
        """Test LOGGER has the correct module name."""
        assert "aiokwikset" in LOGGER.name

    def test_logger_can_log(self) -> None:
        """Test LOGGER can be used for logging."""
        # Should not raise any exceptions
        LOGGER.debug("Test debug message")
        LOGGER.info("Test info message")
        LOGGER.warning("Test warning message")


# ============================================================================
# Type Tests
# ============================================================================


class TestConstantTypes:
    """Tests for constant type annotations."""

    def test_all_urls_are_strings(self) -> None:
        """Test all URL constants are strings."""
        urls = [
            API_BASE_URL,
            GET_USER_URL,
            GET_HOMES_URL,
            GET_HOME_DEVICES_URL,
            GET_DEVICE_URL,
            LOCK_COMMAND_URL,
            ACCESSORY_COMMAND_URL,
        ]

        for url in urls:
            assert isinstance(url, str), f"URL {url} should be string"

    def test_all_headers_are_strings(self) -> None:
        """Test all header constants are strings."""
        headers = [
            LOGIN_HEADER_USER_AGENT,
            DEFAULT_HEADER_USER_AGENT,
            DEFAULT_HEADER_ACCEPT_ENCODING,
        ]

        for header in headers:
            assert isinstance(header, str), "Header should be string"

    def test_cognito_config_are_strings(self) -> None:
        """Test all Cognito config constants are strings."""
        configs = [
            POOL_ID,
            CLIENT_ID,
            POOL_REGION,
        ]

        for config in configs:
            assert isinstance(config, str), "Config should be string"
