// OpenPGP cleartext-signature envelope tests: detection, extraction,
// dash-unescaping and malformed-envelope rejection. No signature is ever
// verified — the library only reports `SignedUnverified`.

///|
fn signed_fixture() -> String {
  "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA256\n\nContact: mailto:security@example.com\nExpires: 2027-01-01T00:00:00Z\n-----BEGIN PGP SIGNATURE-----\n\niQEzBAABCAAdFiEEfake-signature-block\n=\n-----END PGP SIGNATURE-----\n"
}

///|
test "signed envelope is detected, the cleartext parses and armor headers are captured" {
  let document = unwrap_parse(signed_fixture())
  assert_true(document.is_signed())
  assert_true(document.signature_state() == SignedUnverified)
  assert_int_eq(document.contacts().length(), 1)
  assert_str_eq(document.contacts()[0], "mailto:security@example.com")
  assert_str_eq(document.expires_value().unwrap(), "2027-01-01T00:00:00Z")
  let headers = document.armor_headers()
  assert_int_eq(headers.length(), 1)
  assert_str_eq(headers[0], "Hash: SHA256")
}

///|
test "unsigned input is not detected as signed" {
  let document = unwrap_parse(valid_document())
  assert_false(document.is_signed())
  assert_true(document.signature_state() == Unsigned)
  assert_int_eq(document.armor_headers().length(), 0)
}

///|
test "dash-escaped cleartext is unescaped" {
  // RFC 4880: a cleartext comment starting with '-' is written as "- " + line.
  let input = "-----BEGIN PGP SIGNED MESSAGE-----\n\n- # comment written through dash-escaping\nContact: mailto:a@example.com\n-----BEGIN PGP SIGNATURE-----\n\nfake\n-----END PGP SIGNATURE-----\n"
  let document = unwrap_parse(input)
  assert_int_eq(document.comments().length(), 1)
  assert_str_eq(
    document.comments()[0],
    " comment written through dash-escaping",
  )
}

///|
test "malformed envelopes are rejected with InvalidSignatureEnvelope" {
  // Armor headers must be followed by a blank line.
  let no_blank = "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA256\nContact: mailto:a@example.com\n"
  let err1 = expect_parse_error(no_blank)
  assert_err_kind(err1, InvalidSignatureEnvelope)
  // The signature begin marker is required.
  let no_begin = "-----BEGIN PGP SIGNED MESSAGE-----\n\nContact: mailto:a@example.com\n"
  let err2 = expect_parse_error(no_begin)
  assert_err_kind(err2, InvalidSignatureEnvelope)
  // The signature end marker is required.
  let no_end = "-----BEGIN PGP SIGNED MESSAGE-----\n\nContact: mailto:a@example.com\n-----BEGIN PGP SIGNATURE-----\n\nfake\n"
  let err3 = expect_parse_error(no_end)
  assert_err_kind(err3, InvalidSignatureEnvelope)
  // Content after the signature block is not part of the cleartext.
  let trailing = "\{signed_fixture()}Contact: mailto:evil@example.com\n"
  let err4 = expect_parse_error(trailing)
  assert_err_kind(err4, InvalidSignatureEnvelope)
}

///|
test "extract_cleartext returns the joined body for signed input" {
  match extract_cleartext(signed_fixture()) {
    Ok(Some(body)) => {
      assert_true(body.has_prefix("Contact: mailto:security@example.com\n"))
      assert_true(body.has_suffix("\n-----BEGIN PGP SIGNATURE-----") == false)
    }
    _ => fail("expected extracted cleartext")
  }
}

///|
test "extract_cleartext returns None for unsigned input" {
  match extract_cleartext(valid_document()) {
    Ok(None) => ()
    _ => fail("expected None for unsigned input")
  }
}