package cloud.nstart.terravault.ordinis.outbox.webhook;

import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class HmacSignerTest {

  // Reference value computed via:
  //   echo -n "hello" | openssl dgst -sha256 -hmac "secret"
  //   = 88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b
  private static final String KNOWN_SECRET = "secret";
  private static final String KNOWN_BODY = "hello";
  private static final String KNOWN_SIG = "sha256=88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b";

  @Test
  void signsKnownVectorCorrectly() {
    String sig = HmacSigner.sign(KNOWN_SECRET, KNOWN_BODY.getBytes(StandardCharsets.UTF_8));
    assertThat(sig).isEqualTo(KNOWN_SIG);
  }

  @Test
  void signaturePrefixedWithSha256() {
    String sig = HmacSigner.sign("any-secret", "body".getBytes());
    assertThat(sig).startsWith("sha256=");
  }

  @Test
  void hexLengthIs64Chars() {
    String sig = HmacSigner.sign("any-secret", "body".getBytes());
    // "sha256=" = 7 chars + 64 hex = 71
    assertThat(sig).hasSize(71);
    assertThat(sig.substring(7)).matches("[0-9a-f]{64}");
  }

  @Test
  void differentBodyProducesDifferentSignature() {
    String sig1 = HmacSigner.sign("secret", "body1".getBytes());
    String sig2 = HmacSigner.sign("secret", "body2".getBytes());
    assertThat(sig1).isNotEqualTo(sig2);
  }

  @Test
  void differentSecretProducesDifferentSignature() {
    String sig1 = HmacSigner.sign("secret-a", "body".getBytes());
    String sig2 = HmacSigner.sign("secret-b", "body".getBytes());
    assertThat(sig1).isNotEqualTo(sig2);
  }

  @Test
  void emptySecretRejected() {
    assertThatThrownBy(() -> HmacSigner.sign("", "body".getBytes()))
        .isInstanceOf(IllegalArgumentException.class);
    assertThatThrownBy(() -> HmacSigner.sign(null, "body".getBytes()))
        .isInstanceOf(IllegalArgumentException.class);
  }

  @Test
  void emptyBodySignsCleanly() {
    // Empty body must produce a deterministic signature, not throw
    String sig = HmacSigner.sign("secret", new byte[0]);
    assertThat(sig).startsWith("sha256=");
    assertThat(sig.substring(7)).matches("[0-9a-f]{64}");
  }

  @Test
  void headerNameConstant() {
    assertThat(HmacSigner.HEADER_NAME).isEqualTo("X-Ordinis-Signature");
  }
}
