package com.saas.shared.security;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@TestPropertySource(properties = {
    "VAPI_WEBHOOK_SECRET=test_vapi_secret",
    "RETELL_WEBHOOK_SECRET=test_retell_secret",
    "TWILIO_WEBHOOK_SECRET=twilio_auth_token"
})
@DisplayName("WebhookSecurityService Verification Tests")
public class WebhookSecurityServiceTest {

    @Autowired
    private WebhookSecurityService webhookSecurityService;

    @Test
    @DisplayName("Vapi signature verification with invalid signature should fail")
    void testVapiSignatureInvalid() {
        String payload = "{\"event\":\"call_started\"}";
        String invalidSignature = "invalid_base64_signature";

        assertFalse(webhookSecurityService.verifyVapiSignature(payload, invalidSignature),
                "Invalid Vapi signature should not verify");
    }

    @Test
    @DisplayName("Vapi signature verification with missing signature should fail")
    void testVapiSignatureMissing() {
        String payload = "{\"event\":\"call_started\"}";
        String missingSignature = "";

        assertFalse(webhookSecurityService.verifyVapiSignature(payload, missingSignature),
                "Missing Vapi signature should not verify");
    }

    @Test
    @DisplayName("Twilio signature verification with invalid signature should fail")
    void testTwilioSignatureInvalid() {
        String requestUrl = "http://localhost:5000/api/voip/twilio/status-callback";
        String canonicalData = "CallSidCA123CallStatuscompleted";
        String invalidSignature = "invalid_twilio_sig";

        assertFalse(webhookSecurityService.verifyTwilioSignature(requestUrl, canonicalData, invalidSignature),
                "Invalid Twilio signature should not verify");
    }

    @Test
    @DisplayName("Retell signature verification with invalid signature should fail")
    void testRetellSignatureInvalid() {
        String payload = "{\"event\":\"call_ended\"}";
        String invalidSignature = "wrong_signature";

        assertFalse(webhookSecurityService.verifyRetellSignature(payload, invalidSignature),
                "Invalid Retell signature should not verify");
    }

    @Test
    @DisplayName("Vapi verification rejects tampered payload with original signature")
    void testVapiTamperedPayload() {
        // This tests that if payload is modified after signing, verification fails
        String originalPayload = "{\"event\":\"call_started\",\"callId\":\"123\"}";
        String tamperedPayload = "{\"event\":\"call_ended\",\"callId\":\"123\"}";
        
        // Even if we had a valid signature for original, it wouldn't work for tampered
        String fakeSignature = "aW52YWxpZF9zaWduYXR1cmU=";  // base64 of "invalid_signature"
        
        assertFalse(webhookSecurityService.verifyVapiSignature(tamperedPayload, fakeSignature),
                "Tampered payload with signature should fail verification");
    }

    @Test
    @DisplayName("Twilio verification rejects invalid base64 signature")
    void testTwilioInvalidBase64Signature() {
        String requestUrl = "http://localhost:5000/api/voip/twilio/status-callback";
        String canonicalData = "CallSidCA123";
        String invalidBase64 = "this_is_not_base64!!!";  // Not valid base64
        
        assertFalse(webhookSecurityService.verifyTwilioSignature(requestUrl, canonicalData, invalidBase64),
                "Invalid base64 signature should fail");
    }

    @Test
    @DisplayName("Retell verification rejects malformed signature")
    void testRetellMalformedSignature() {
        String payload = "{\"event\":\"call_ended\"}";
        String malformedSignature = "!!!not_base64!!!";
        
        assertFalse(webhookSecurityService.verifyRetellSignature(payload, malformedSignature),
                "Malformed signature should fail verification");
    }
}
