"""MPS REST API v1 — HMAC-signed requests.

Auth scheme
-----------
Every request must include three headers:

  X-MPS-Key:       mps_pub_{32 hex}   — identifies the key pair
  X-MPS-Timestamp: {unix seconds}     — replay protection (±300 s window)
  X-MPS-Signature: sha256={hex}       — HMAC-SHA256 over string_to_sign

string_to_sign = "{METHOD}\\n{PATH}\\n{TIMESTAMP}\\n{SHA256_OF_BODY_HEX}"

The secret key signs the request client-side and is verified server-side.
It never travels over the wire.
"""

import logging

from pyramid.httpexceptions import HTTPUnauthorized

from ...models.api_key import get_api_key_by_public_key

log = logging.getLogger(__name__)


def api_key_required(fn):
    """Decorator: verify HMAC signature, attach (api_key, shop) to request."""

    def inner(request):
        public_key = request.headers.get("X-MPS-Key", "")
        timestamp = request.headers.get("X-MPS-Timestamp", "")
        signature = request.headers.get("X-MPS-Signature", "")

        if not public_key or not timestamp or not signature:
            raise HTTPUnauthorized(
                json_body={"error": "Missing auth headers: X-MPS-Key, X-MPS-Timestamp, X-MPS-Signature"}
            )

        api_key = get_api_key_by_public_key(request.dbsession, public_key)
        if api_key is None:
            raise HTTPUnauthorized(json_body={"error": "Unknown or revoked API key"})

        body_bytes = request.body if request.body else b""

        if not api_key.verify_signature(
            request.method,
            request.path,
            timestamp,
            body_bytes,
            signature,
        ):
            raise HTTPUnauthorized(json_body={"error": "Invalid signature"})

        # Update last_used without waiting for transaction commit
        from ...models.meta import now_timestamp
        api_key.last_used_timestamp = now_timestamp()
        request.dbsession.add(api_key)

        request.api_key = api_key
        request.api_shop = api_key.shop
        return fn(request)

    return inner
