"""
AWS request signing for API Gateway IAM authentication.

Follows CLAUDE.md: Single responsibility, dependency injection, <50 lines/method.
"""

import boto3
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from typing import Dict, Optional
from urllib.parse import urlparse


class AWSRequestSigner:
    """
    Signs HTTP requests with AWS SigV4 for IAM authentication.

    Single responsibility: Sign requests using AWS credentials.
    Dependencies injected: AWS session (optional).
    """

    def __init__(self, session: Optional[boto3.Session] = None):
        """
        Initialize request signer.

        Args:
            session: AWS session (uses default credentials if not provided)
        """
        self.session = session or boto3.Session()
        self.credentials = self.session.get_credentials()

    def sign_request(
        self,
        method: str,
        url: str,
        headers: Optional[Dict[str, str]] = None,
        body: Optional[str] = None
    ) -> Dict[str, str]:
        """
        Sign HTTP request with AWS SigV4.

        Args:
            method: HTTP method (GET, POST, etc.)
            url: Full request URL
            headers: Request headers
            body: Request body (for POST/PUT)

        Returns:
            Signed headers to include in request
        """
        # Extract region and service from URL
        parsed_url = urlparse(url)
        region = self._extract_region(parsed_url.hostname)

        # Create AWS request object
        aws_request = AWSRequest(
            method=method,
            url=url,
            headers=headers or {},
            data=body
        )

        # Sign request with SigV4
        SigV4Auth(self.credentials, "execute-api", region).add_auth(aws_request)

        # Return signed headers
        return dict(aws_request.headers)

    def _extract_region(self, hostname: str) -> str:
        """
        Extract AWS region from API Gateway hostname.

        Args:
            hostname: API Gateway hostname (e.g., xyz.execute-api.us-east-1.amazonaws.com)

        Returns:
            AWS region (e.g., us-east-1)
        """
        # API Gateway URL format: {api-id}.execute-api.{region}.amazonaws.com
        parts = hostname.split(".")
        if len(parts) >= 4 and parts[1] == "execute-api":
            return parts[2]

        # Default to us-east-1 if parsing fails
        return "us-east-1"
