use std::borrow::Cow;

use kameleoon_trace_logging::trace_method;
use urlencoding::encode;

use crate::logging::LogLevel;

pub(crate) struct UrlEncoder;

impl UrlEncoder {
    #[trace_method(LogLevel::Debug)]
    pub fn encode_uri_component(input: &str) -> Cow<'_, str> {
        encode(input)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use rstest::rstest;
    use std::borrow::Cow;

    #[rstest]
    #[case("hello world", "hello%20world")]
    #[case("abc123", "abc123")]
    #[case("!*'();:@&=+$,/?#[]", "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D")]
    #[case("你好，世界", "%E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C")]
    #[case(
        "https://google.com?key='aaa~aaa'&val_ue=10&aa@a-3 3 3-_.!~*'()",
        "https%3A%2F%2Fgoogle.com%3Fkey%3D%27aaa~aaa%27%26val_ue%3D10%26aa%40a-3%203%203-_.%21~%2A%27%28%29"
    )]
    #[case("", "")]
    fn test_encode_uri_component(#[case] input: &str, #[case] expected: &str) {
        let result = UrlEncoder::encode_uri_component(input);
        assert_eq!(result, expected);
    }

    #[test]
    fn test_returns_borrowed_for_safe_ascii() {
        let input = "abc123";
        let result = UrlEncoder::encode_uri_component(input);
        assert!(matches!(result, Cow::Borrowed(_)));
    }
}
