// Copyright 2023 Salesforce, Inc. All rights reserved.
use crate::HeaderValue;

const ALLOWED_METHODS: [&str; 3] = [
    "application/x-www-form-urlencoded",
    "multipart/form-data",
    "text/plain",
];

pub trait ContentMatcher {
    fn matches(&self, value: &HeaderValue) -> bool;
}

#[derive(Default)]
pub(crate) struct AllowedContentTypeValues {}

impl ContentMatcher for AllowedContentTypeValues {
    fn matches(&self, value: &HeaderValue) -> bool {
        ALLOWED_METHODS
            .iter()
            .any(|allowed| allowed.eq_ignore_ascii_case(value))
    }
}

#[cfg(test)]
mod allowed_content_type_values_test {
    use super::AllowedContentTypeValues;
    use crate::model::request::simple_request_content_type::ContentMatcher;

    #[test]
    fn allowed_lowercase_content_type_value_matches() {
        let content_type = AllowedContentTypeValues::default();

        assert!(content_type.matches("application/x-www-form-urlencoded"));
        assert!(content_type.matches("multipart/form-data"));
        assert!(content_type.matches("text/plain"));
    }

    #[test]
    fn allowed_uppercase_content_type_value_matches() {
        let content_type = AllowedContentTypeValues::default();

        assert!(content_type.matches("APPLICATION/X-WWW-FORM-URLENCODED"));
        assert!(content_type.matches("MULTIPART/FORM-DATA"));
        assert!(content_type.matches("TEXT/PLAIN"));
    }

    #[test]
    fn allowed_mixed_case_content_type_value_matches() {
        let content_type = AllowedContentTypeValues::default();

        assert!(content_type.matches("Application/X-WWW-Form-Urlencoded"));
        assert!(content_type.matches("Multipart/Form-Data"));
        assert!(content_type.matches("Text/Plain"));
    }

    #[test]
    fn not_allowed_content_type_does_not_match() {
        let content_type = AllowedContentTypeValues::default();

        assert!(!content_type.matches("application/json"));
        assert!(!content_type.matches("multipart/digest"));
        assert!(!content_type.matches("text/html"));
    }
}
