use hickory_proto::op::Message;

/// Errors that can occur when parsing a DNS query.
#[derive(Debug, thiserror::Error)]
pub enum QueryParseError {
    /// The wire-format bytes are not a valid DNS message.
    #[error("invalid DNS message: {0}")]
    InvalidMessage(#[from] hickory_proto::ProtoError),
}

/// Parse raw bytes into a DNS [`Message`].
///
/// This is used to decode incoming DNS wire-format queries received
/// over the DoH endpoint (RFC 8484).
pub fn parse_query(buf: &[u8]) -> Result<Message, QueryParseError> {
    let message = Message::from_vec(buf)?;
    Ok(message)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_valid_dns_query() {
        // Minimal valid DNS query for "example.com" A record
        #[rustfmt::skip]
        let buf: Vec<u8> = vec![
            0xAB, 0xCD, // transaction ID
            0x01, 0x00, // flags: standard query, recursion desired
            0x00, 0x01, // 1 question
            0x00, 0x00, // 0 answers
            0x00, 0x00, // 0 authority
            0x00, 0x00, // 0 additional
            // question: example.com A IN
            0x07, b'e', b'x', b'a', b'm', b'p', b'l', b'e',
            0x03, b'c', b'o', b'm',
            0x00,       // root label
            0x00, 0x01, // type A
            0x00, 0x01, // class IN
        ];

        let message = parse_query(&buf).unwrap();
        assert_eq!(message.id(), 0xABCD);
        assert_eq!(message.queries().len(), 1);
        assert_eq!(message.queries()[0].name().to_string(), "example.com.");
    }

    #[test]
    fn test_parse_invalid_bytes_returns_error() {
        let buf = vec![0x00; 3]; // too short
        let result = parse_query(&buf);
        assert!(result.is_err());
    }
}
