"""Tests for webhook utilities."""

import hashlib
import hmac
import json

import pytest

from kawaa import ValidationError
from kawaa.webhooks import parse_webhook, verify_signature, WebhookEvent


class TestVerifySignature:
    """Tests for signature verification."""

    def test_valid_signature(self):
        """Test verifying a valid signature."""
        payload = b'{"event": "job.completed", "job_id": "123"}'
        secret = "my-secret-key"

        # Generate correct signature
        signature = hmac.new(
            secret.encode("utf-8"),
            payload,
            hashlib.sha256,
        ).hexdigest()

        assert verify_signature(payload, f"sha256={signature}", secret) is True

    def test_valid_signature_without_prefix(self):
        """Test signature without sha256= prefix."""
        payload = b'{"event": "job.completed"}'
        secret = "secret"

        signature = hmac.new(
            secret.encode("utf-8"),
            payload,
            hashlib.sha256,
        ).hexdigest()

        assert verify_signature(payload, signature, secret) is True

    def test_invalid_signature(self):
        """Test rejecting invalid signature."""
        payload = b'{"event": "job.completed"}'
        secret = "correct-secret"

        # Wrong signature
        assert verify_signature(payload, "sha256=invalid", secret) is False

    def test_empty_signature(self):
        """Test rejecting empty signature."""
        payload = b'{"event": "job.completed"}'
        secret = "secret"

        assert verify_signature(payload, "", secret) is False

    def test_empty_secret(self):
        """Test rejecting empty secret."""
        payload = b'{"event": "job.completed"}'

        assert verify_signature(payload, "sha256=abc", "") is False


class TestParseWebhook:
    """Tests for parsing webhook payloads."""

    def test_parse_valid_payload(self):
        """Test parsing a valid webhook payload."""
        payload = json.dumps({
            "event": "job.completed",
            "job_id": "job-123",
            "status": "completed",
            "created_at": "2024-01-01T00:00:00Z",
            "completed_at": "2024-01-01T00:01:00Z",
            "results": {
                "total": 100,
                "valid": 80,
                "invalid": 10,
                "risky": 5,
                "unknown": 5,
            },
            "download_url": "https://api.kawaa.com/v1/jobs/job-123/download",
        }).encode("utf-8")

        event = parse_webhook(payload)

        assert event.event == "job.completed"
        assert event.job_id == "job-123"
        assert event.total == 100
        assert event.valid == 80
        assert event.download_url == "https://api.kawaa.com/v1/jobs/job-123/download"

    def test_parse_with_valid_signature(self):
        """Test parsing with signature verification."""
        payload = json.dumps({
            "event": "job.completed",
            "job_id": "job-123",
            "status": "completed",
            "results": {"total": 10, "valid": 10, "invalid": 0, "risky": 0, "unknown": 0},
            "download_url": "",
        }).encode("utf-8")
        secret = "my-secret"

        signature = "sha256=" + hmac.new(
            secret.encode("utf-8"),
            payload,
            hashlib.sha256,
        ).hexdigest()

        event = parse_webhook(payload, signature, secret)
        assert event.job_id == "job-123"

    def test_parse_with_invalid_signature(self):
        """Test rejecting invalid signature."""
        payload = b'{"event": "job.completed", "job_id": "123"}'
        secret = "correct-secret"

        with pytest.raises(ValidationError) as exc_info:
            parse_webhook(payload, "sha256=wrong", secret)

        assert "Invalid webhook signature" in str(exc_info.value)

    def test_parse_invalid_json(self):
        """Test rejecting invalid JSON."""
        payload = b"not valid json"

        with pytest.raises(ValidationError) as exc_info:
            parse_webhook(payload)

        assert "Invalid JSON" in str(exc_info.value)


class TestWebhookEvent:
    """Tests for WebhookEvent model."""

    def test_from_dict(self):
        """Test creating event from dict."""
        data = {
            "event": "job.completed",
            "job_id": "job-456",
            "status": "completed",
            "results": {
                "total": 50,
                "valid": 40,
                "invalid": 5,
                "risky": 3,
                "unknown": 2,
            },
            "download_url": "https://example.com/download",
        }

        event = WebhookEvent.from_dict(data)

        assert event.event == "job.completed"
        assert event.job_id == "job-456"
        assert event.total == 50
        assert event.valid == 40
        assert event.raw_payload == data
