use std::fmt;
#[cfg(feature = "socks")]
use std::net::SocketAddr;
use std::sync::Arc;

use crate::into_url::{IntoUrl, IntoUrlSealed};
use crate::Url;
use http::{header::HeaderValue, Uri};
use ipnet::IpNet;
use once_cell::sync::Lazy;
use percent_encoding::percent_decode;
use std::collections::HashMap;
use std::env;
use std::error::Error;
use std::net::IpAddr;
#[cfg(target_os = "windows")]
use winreg::enums::HKEY_CURRENT_USER;
#[cfg(target_os = "windows")]
use winreg::RegKey;

/// Configuration of a proxy that a `Client` should pass requests to.
///
/// A `Proxy` has a couple pieces to it:
///
/// - a URL of how to talk to the proxy
/// - rules on what `Client` requests should be directed to the proxy
///
/// For instance, let's look at `Proxy::http`:
///
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let proxy = reqwest::Proxy::http("https://secure.example")?;
/// # Ok(())
/// # }
/// ```
///
/// This proxy will intercept all HTTP requests, and make use of the proxy
/// at `https://secure.example`. A request to `http://hyper.rs` will talk
/// to your proxy. A request to `https://hyper.rs` will not.
///
/// Multiple `Proxy` rules can be configured for a `Client`. The `Client` will
/// check each `Proxy` in the order it was added. This could mean that a
/// `Proxy` added first with eager intercept rules, such as `Proxy::all`,
/// would prevent a `Proxy` later in the list from ever working, so take care.
///
/// By enabling the `"socks"` feature it is possible to use a socks proxy:
/// ```rust
/// # fn run() -> Result<(), Box<std::error::Error>> {
/// let proxy = reqwest::Proxy::http("socks5://192.168.1.1:9000")?;
/// # Ok(())
/// # }
/// ```
#[derive(Clone)]
pub struct Proxy {
    intercept: Intercept,
    no_proxy: Option<NoProxy>,
}

/// Represents a possible matching entry for an IP address
#[derive(Clone, Debug)]
enum Ip {
    Address(IpAddr),
    Network(IpNet),
}

/// A wrapper around a list of IP cidr blocks or addresses with a [IpMatcher::contains] method for
/// checking if an IP address is contained within the matcher
#[derive(Clone, Debug, Default)]
struct IpMatcher(Vec<Ip>);

/// A wrapper around a list of domains with a [DomainMatcher::contains] method for checking if a
/// domain is contained within the matcher
#[derive(Clone, Debug, Default)]
struct DomainMatcher(Vec<String>);

/// A configuration for filtering out requests that shouldn't be proxied
#[derive(Clone, Debug, Default)]
pub struct NoProxy {
    ips: IpMatcher,
    domains: DomainMatcher,
}

/// A particular scheme used for proxying requests.
///
/// For example, HTTP vs SOCKS5
#[derive(Clone)]
pub enum ProxyScheme {
    Http {
        auth: Option<HeaderValue>,
        host: http::uri::Authority,
    },
    Https {
        auth: Option<HeaderValue>,
        host: http::uri::Authority,
    },
    #[cfg(feature = "socks")]
    Socks5 {
        addr: SocketAddr,
        auth: Option<(String, String)>,
        remote_dns: bool,
    },
}

impl ProxyScheme {
    fn maybe_http_auth(&self) -> Option<&HeaderValue> {
        match self {
            ProxyScheme::Http { auth, .. } | ProxyScheme::Https { auth, .. } => auth.as_ref(),
            #[cfg(feature = "socks")]
            _ => None,
        }
    }
}

/// Trait used for converting into a proxy scheme. This trait supports
/// parsing from a URL-like type, whilst also supporting proxy schemes
/// built directly using the factory methods.
pub trait IntoProxyScheme {
    fn into_proxy_scheme(self) -> crate::Result<ProxyScheme>;
}

impl<S: IntoUrl> IntoProxyScheme for S {
    fn into_proxy_scheme(self) -> crate::Result<ProxyScheme> {
        // validate the URL
        let url = match self.as_str().into_url() {
            Ok(ok) => ok,
            Err(e) => {
                let mut presumed_to_have_scheme = true;
                let mut source = e.source();
                while let Some(err) = source {
                    if let Some(parse_error) = err.downcast_ref::<url::ParseError>() {
                        match parse_error {
                            url::ParseError::RelativeUrlWithoutBase => {
                                presumed_to_have_scheme = false;
                                break;
                            }
                            _ => {}
                        }
                    } else if let Some(_) = err.downcast_ref::<crate::error::BadScheme>() {
                        presumed_to_have_scheme = false;
                        break;
                    }
                    source = err.source();
                }
                if !presumed_to_have_scheme {
                    // the issue could have been caused by a missing scheme, so we try adding http://
                    let try_this = format!("http://{}", self.as_str());
                    try_this.into_url().map_err(|_| {
                        // return the original error
                        crate::error::builder(e)
                    })?
                } else {
                    return Err(crate::error::builder(e));
                }
            }
        };
        ProxyScheme::parse(url)
    }
}

// These bounds are accidentally leaked by the blanket impl of IntoProxyScheme
// for all types that implement IntoUrl. So, this function exists to detect
// if we were to break those bounds for a user.
fn _implied_bounds() {
    fn prox<T: IntoProxyScheme>(_t: T) {}

    fn url<T: IntoUrl>(t: T) {
        prox(t);
    }
}

impl IntoProxyScheme for ProxyScheme {
    fn into_proxy_scheme(self) -> crate::Result<ProxyScheme> {
        Ok(self)
    }
}

impl Proxy {
    /// Proxy all HTTP traffic to the passed URL.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let client = reqwest::Client::builder()
    ///     .proxy(reqwest::Proxy::http("https://my.prox")?)
    ///     .build()?;
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn http<U: IntoProxyScheme>(proxy_scheme: U) -> crate::Result<Proxy> {
        Ok(Proxy::new(Intercept::Http(
            proxy_scheme.into_proxy_scheme()?,
        )))
    }

    /// Proxy all HTTPS traffic to the passed URL.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let client = reqwest::Client::builder()
    ///     .proxy(reqwest::Proxy::https("https://example.prox:4545")?)
    ///     .build()?;
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn https<U: IntoProxyScheme>(proxy_scheme: U) -> crate::Result<Proxy> {
        Ok(Proxy::new(Intercept::Https(
            proxy_scheme.into_proxy_scheme()?,
        )))
    }

    /// Proxy **all** traffic to the passed URL.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let client = reqwest::Client::builder()
    ///     .proxy(reqwest::Proxy::all("http://pro.xy")?)
    ///     .build()?;
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn all<U: IntoProxyScheme>(proxy_scheme: U) -> crate::Result<Proxy> {
        Ok(Proxy::new(Intercept::All(
            proxy_scheme.into_proxy_scheme()?,
        )))
    }

    /// Provide a custom function to determine what traffic to proxy to where.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let target = reqwest::Url::parse("https://my.prox")?;
    /// let client = reqwest::Client::builder()
    ///     .proxy(reqwest::Proxy::custom(move |url| {
    ///         if url.host_str() == Some("hyper.rs") {
    ///             Some(target.clone())
    ///         } else {
    ///             None
    ///         }
    ///     }))
    ///     .build()?;
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn custom<F, U: IntoProxyScheme>(fun: F) -> Proxy
    where
        F: Fn(&Url) -> Option<U> + Send + Sync + 'static,
    {
        Proxy::new(Intercept::Custom(Custom {
            auth: None,
            func: Arc::new(move |url| fun(url).map(IntoProxyScheme::into_proxy_scheme)),
        }))
    }

    pub(crate) fn system() -> Proxy {
        let mut proxy = if cfg!(feature = "__internal_proxy_sys_no_cache") {
            Proxy::new(Intercept::System(Arc::new(get_sys_proxies(
                get_from_registry(),
            ))))
        } else {
            Proxy::new(Intercept::System(SYS_PROXIES.clone()))
        };
        proxy.no_proxy = NoProxy::from_env();
        proxy
    }

    fn new(intercept: Intercept) -> Proxy {
        Proxy {
            intercept,
            no_proxy: None,
        }
    }

    /// Set the `Proxy-Authorization` header using Basic auth.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let proxy = reqwest::Proxy::https("http://localhost:1234")?
    ///     .basic_auth("Aladdin", "open sesame");
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn basic_auth(mut self, username: &str, password: &str) -> Proxy {
        self.intercept.set_basic_auth(username, password);
        self
    }

    /// Adds a `No Proxy` exclusion list to this Proxy
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<std::error::Error>> {
    /// let proxy = reqwest::Proxy::https("http://localhost:1234")?
    ///     .no_proxy(reqwest::NoProxy::from_string("direct.tld, sub.direct2.tld"));
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    pub fn no_proxy(mut self, no_proxy: Option<NoProxy>) -> Proxy {
        self.no_proxy = no_proxy;
        self
    }

    pub(crate) fn maybe_has_http_auth(&self) -> bool {
        match &self.intercept {
            Intercept::All(p) | Intercept::Http(p) => p.maybe_http_auth().is_some(),
            // Custom *may* match 'http', so assume so.
            Intercept::Custom(_) => true,
            Intercept::System(system) => system
                .get("http")
                .and_then(|s| s.maybe_http_auth())
                .is_some(),
            _ => false,
        }
    }

    pub(crate) fn http_basic_auth<D: Dst>(&self, uri: &D) -> Option<HeaderValue> {
        match &self.intercept {
            Intercept::All(p) | Intercept::Http(p) => p.maybe_http_auth().cloned(),
            Intercept::System(system) => system
                .get("http")
                .and_then(|s| s.maybe_http_auth().cloned()),
            Intercept::Custom(custom) => {
                custom.call(uri).and_then(|s| s.maybe_http_auth().cloned())
            }
            _ => None,
        }
    }

    pub(crate) fn intercept<D: Dst>(&self, uri: &D) -> Option<ProxyScheme> {
        let in_no_proxy = self
            .no_proxy
            .as_ref()
            .map_or(false, |np| np.contains(uri.host()));
        match self.intercept {
            Intercept::All(ref u) => {
                if !in_no_proxy {
                    Some(u.clone())
                } else {
                    None
                }
            }
            Intercept::Http(ref u) => {
                if !in_no_proxy && uri.scheme() == "http" {
                    Some(u.clone())
                } else {
                    None
                }
            }
            Intercept::Https(ref u) => {
                if !in_no_proxy && uri.scheme() == "https" {
                    Some(u.clone())
                } else {
                    None
                }
            }
            Intercept::System(ref map) => {
                if in_no_proxy {
                    None
                } else {
                    map.get(uri.scheme()).cloned()
                }
            }
            Intercept::Custom(ref custom) => {
                if !in_no_proxy {
                    custom.call(uri)
                } else {
                    None
                }
            }
        }
    }

    pub(crate) fn is_match<D: Dst>(&self, uri: &D) -> bool {
        match self.intercept {
            Intercept::All(_) => true,
            Intercept::Http(_) => uri.scheme() == "http",
            Intercept::Https(_) => uri.scheme() == "https",
            Intercept::System(ref map) => map.contains_key(uri.scheme()),
            Intercept::Custom(ref custom) => custom.call(uri).is_some(),
        }
    }
}

impl fmt::Debug for Proxy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_tuple("Proxy")
            .field(&self.intercept)
            .field(&self.no_proxy)
            .finish()
    }
}

impl NoProxy {
    /// Returns a new no-proxy configuration based on environment variables (or `None` if no variables are set)
    /// see [self::NoProxy::from_string()] for the string format
    pub fn from_env() -> Option<NoProxy> {
        let raw = env::var("NO_PROXY")
            .or_else(|_| env::var("no_proxy"))
            .unwrap_or_default();

        Self::from_string(&raw)
    }

    /// Returns a new no-proxy configuration based on a no_proxy string (or `None` if no variables
    /// are set)
    /// The rules are as follows:
    /// * The environment variable `NO_PROXY` is checked, if it is not set, `no_proxy` is checked
    /// * If neither environment variable is set, `None` is returned
    /// * Entries are expected to be comma-separated (whitespace between entries is ignored)
    /// * IP addresses (both IPv4 and IPv6) are allowed, as are optional subnet masks (by adding /size,
    /// for example "`192.168.1.0/24`").
    /// * An entry "`*`" matches all hostnames (this is the only wildcard allowed)
    /// * Any other entry is considered a domain name (and may contain a leading dot, for example `google.com`
    /// and `.google.com` are equivalent) and would match both that domain AND all subdomains.
    ///
    /// For example, if `"NO_PROXY=google.com, 192.168.1.0/24"` was set, all of the following would match
    /// (and therefore would bypass the proxy):
    /// * `http://google.com/`
    /// * `http://www.google.com/`
    /// * `http://192.168.1.42/`
    ///
    /// The URL `http://notgoogle.com/` would not match.
    pub fn from_string(no_proxy_list: &str) -> Option<Self> {
        if no_proxy_list.is_empty() {
            return None;
        }
        let mut ips = Vec::new();
        let mut domains = Vec::new();
        let parts = no_proxy_list.split(',').map(str::trim);
        for part in parts {
            match part.parse::<IpNet>() {
                // If we can parse an IP net or address, then use it, otherwise, assume it is a domain
                Ok(ip) => ips.push(Ip::Network(ip)),
                Err(_) => match part.parse::<IpAddr>() {
                    Ok(addr) => ips.push(Ip::Address(addr)),
                    Err(_) => domains.push(part.to_owned()),
                },
            }
        }
        Some(NoProxy {
            ips: IpMatcher(ips),
            domains: DomainMatcher(domains),
        })
    }

    fn contains(&self, host: &str) -> bool {
        // According to RFC3986, raw IPv6 hosts will be wrapped in []. So we need to strip those off
        // the end in order to parse correctly
        let host = if host.starts_with('[') {
            let x: &[_] = &['[', ']'];
            host.trim_matches(x)
        } else {
            host
        };
        match host.parse::<IpAddr>() {
            // If we can parse an IP addr, then use it, otherwise, assume it is a domain
            Ok(ip) => self.ips.contains(ip),
            Err(_) => self.domains.contains(host),
        }
    }
}

impl IpMatcher {
    fn contains(&self, addr: IpAddr) -> bool {
        for ip in self.0.iter() {
            match ip {
                Ip::Address(address) => {
                    if &addr == address {
                        return true;
                    }
                }
                Ip::Network(net) => {
                    if net.contains(&addr) {
                        return true;
                    }
                }
            }
        }
        false
    }
}

impl DomainMatcher {
    // The following links may be useful to understand the origin of these rules:
    // * https://curl.se/libcurl/c/CURLOPT_NOPROXY.html
    // * https://github.com/curl/curl/issues/1208
    fn contains(&self, domain: &str) -> bool {
        let domain_len = domain.len();
        for d in self.0.iter() {
            if d == domain || d.strip_prefix('.') == Some(domain) {
                return true;
            } else if domain.ends_with(d) {
                if d.starts_with('.') {
                    // If the first character of d is a dot, that means the first character of domain
                    // must also be a dot, so we are looking at a subdomain of d and that matches
                    return true;
                } else if domain.as_bytes().get(domain_len - d.len() - 1) == Some(&b'.') {
                    // Given that d is a prefix of domain, if the prior character in domain is a dot
                    // then that means we must be matching a subdomain of d, and that matches
                    return true;
                }
            } else if d == "*" {
                return true;
            }
        }
        false
    }
}

impl ProxyScheme {
    // To start conservative, keep builders private for now.

    /// Proxy traffic via the specified URL over HTTP
    fn http(host: &str) -> crate::Result<Self> {
        Ok(ProxyScheme::Http {
            auth: None,
            host: host.parse().map_err(crate::error::builder)?,
        })
    }

    /// Proxy traffic via the specified URL over HTTPS
    fn https(host: &str) -> crate::Result<Self> {
        Ok(ProxyScheme::Https {
            auth: None,
            host: host.parse().map_err(crate::error::builder)?,
        })
    }

    /// Proxy traffic via the specified socket address over SOCKS5
    ///
    /// # Note
    ///
    /// Current SOCKS5 support is provided via blocking IO.
    #[cfg(feature = "socks")]
    fn socks5(addr: SocketAddr) -> crate::Result<Self> {
        Ok(ProxyScheme::Socks5 {
            addr,
            auth: None,
            remote_dns: false,
        })
    }

    /// Proxy traffic via the specified socket address over SOCKS5H
    ///
    /// This differs from SOCKS5 in that DNS resolution is also performed via the proxy.
    ///
    /// # Note
    ///
    /// Current SOCKS5 support is provided via blocking IO.
    #[cfg(feature = "socks")]
    fn socks5h(addr: SocketAddr) -> crate::Result<Self> {
        Ok(ProxyScheme::Socks5 {
            addr,
            auth: None,
            remote_dns: true,
        })
    }

    /// Use a username and password when connecting to the proxy server
    fn with_basic_auth<T: Into<String>, U: Into<String>>(
        mut self,
        username: T,
        password: U,
    ) -> Self {
        self.set_basic_auth(username, password);
        self
    }

    fn set_basic_auth<T: Into<String>, U: Into<String>>(&mut self, username: T, password: U) {
        match *self {
            ProxyScheme::Http { ref mut auth, .. } => {
                let header = encode_basic_auth(&username.into(), &password.into());
                *auth = Some(header);
            }
            ProxyScheme::Https { ref mut auth, .. } => {
                let header = encode_basic_auth(&username.into(), &password.into());
                *auth = Some(header);
            }
            #[cfg(feature = "socks")]
            ProxyScheme::Socks5 { ref mut auth, .. } => {
                *auth = Some((username.into(), password.into()));
            }
        }
    }

    fn if_no_auth(mut self, update: &Option<HeaderValue>) -> Self {
        match self {
            ProxyScheme::Http { ref mut auth, .. } => {
                if auth.is_none() {
                    *auth = update.clone();
                }
            }
            ProxyScheme::Https { ref mut auth, .. } => {
                if auth.is_none() {
                    *auth = update.clone();
                }
            }
            #[cfg(feature = "socks")]
            ProxyScheme::Socks5 { .. } => {}
        }

        self
    }

    /// Convert a URL into a proxy scheme
    ///
    /// Supported schemes: HTTP, HTTPS, (SOCKS5, SOCKS5H if `socks` feature is enabled).
    // Private for now...
    fn parse(url: Url) -> crate::Result<Self> {
        use url::Position;

        // Resolve URL to a host and port
        #[cfg(feature = "socks")]
        let to_addr = || {
            let addrs = url
                .socket_addrs(|| match url.scheme() {
                    "socks5" | "socks5h" => Some(1080),
                    _ => None,
                })
                .map_err(crate::error::builder)?;
            addrs
                .into_iter()
                .next()
                .ok_or_else(|| crate::error::builder("unknown proxy scheme"))
        };

        let mut scheme = match url.scheme() {
            "http" => Self::http(&url[Position::BeforeHost..Position::AfterPort])?,
            "https" => Self::https(&url[Position::BeforeHost..Position::AfterPort])?,
            #[cfg(feature = "socks")]
            "socks5" => Self::socks5(to_addr()?)?,
            #[cfg(feature = "socks")]
            "socks5h" => Self::socks5h(to_addr()?)?,
            _ => return Err(crate::error::builder("unknown proxy scheme")),
        };

        if let Some(pwd) = url.password() {
            let decoded_username = percent_decode(url.username().as_bytes()).decode_utf8_lossy();
            let decoded_password = percent_decode(pwd.as_bytes()).decode_utf8_lossy();
            scheme = scheme.with_basic_auth(decoded_username, decoded_password);
        }

        Ok(scheme)
    }

    #[cfg(test)]
    fn scheme(&self) -> &str {
        match self {
            ProxyScheme::Http { .. } => "http",
            ProxyScheme::Https { .. } => "https",
            #[cfg(feature = "socks")]
            ProxyScheme::Socks5 { .. } => "socks5",
        }
    }

    #[cfg(test)]
    fn host(&self) -> &str {
        match self {
            ProxyScheme::Http { host, .. } => host.as_str(),
            ProxyScheme::Https { host, .. } => host.as_str(),
            #[cfg(feature = "socks")]
            ProxyScheme::Socks5 { .. } => panic!("socks5"),
        }
    }
}

impl fmt::Debug for ProxyScheme {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            ProxyScheme::Http { auth: _auth, host } => write!(f, "http://{}", host),
            ProxyScheme::Https { auth: _auth, host } => write!(f, "https://{}", host),
            #[cfg(feature = "socks")]
            ProxyScheme::Socks5 {
                addr,
                auth: _auth,
                remote_dns,
            } => {
                let h = if *remote_dns { "h" } else { "" };
                write!(f, "socks5{}://{}", h, addr)
            }
        }
    }
}

type SystemProxyMap = HashMap<String, ProxyScheme>;
type RegistryProxyValues = (u32, String);

#[derive(Clone, Debug)]
enum Intercept {
    All(ProxyScheme),
    Http(ProxyScheme),
    Https(ProxyScheme),
    System(Arc<SystemProxyMap>),
    Custom(Custom),
}

impl Intercept {
    fn set_basic_auth(&mut self, username: &str, password: &str) {
        match self {
            Intercept::All(ref mut s)
            | Intercept::Http(ref mut s)
            | Intercept::Https(ref mut s) => s.set_basic_auth(username, password),
            Intercept::System(_) => unimplemented!(),
            Intercept::Custom(ref mut custom) => {
                let header = encode_basic_auth(username, password);
                custom.auth = Some(header);
            }
        }
    }
}

#[derive(Clone)]
struct Custom {
    // This auth only applies if the returned ProxyScheme doesn't have an auth...
    auth: Option<HeaderValue>,
    func: Arc<dyn Fn(&Url) -> Option<crate::Result<ProxyScheme>> + Send + Sync + 'static>,
}

impl Custom {
    fn call<D: Dst>(&self, uri: &D) -> Option<ProxyScheme> {
        let url = format!(
            "{}://{}{}{}",
            uri.scheme(),
            uri.host(),
            uri.port().map(|_| ":").unwrap_or(""),
            uri.port().map(|p| p.to_string()).unwrap_or_default()
        )
        .parse()
        .expect("should be valid Url");

        (self.func)(&url)
            .and_then(|result| result.ok())
            .map(|scheme| scheme.if_no_auth(&self.auth))
    }
}

impl fmt::Debug for Custom {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("_")
    }
}

pub(crate) fn encode_basic_auth(username: &str, password: &str) -> HeaderValue {
    crate::util::basic_auth(username, Some(password))
}

/// A helper trait to allow testing `Proxy::intercept` without having to
/// construct `hyper::client::connect::Destination`s.
pub(crate) trait Dst {
    fn scheme(&self) -> &str;
    fn host(&self) -> &str;
    fn port(&self) -> Option<u16>;
}

#[doc(hidden)]
impl Dst for Uri {
    fn scheme(&self) -> &str {
        self.scheme().expect("Uri should have a scheme").as_str()
    }

    fn host(&self) -> &str {
        Uri::host(self).expect("<Uri as Dst>::host should have a str")
    }

    fn port(&self) -> Option<u16> {
        self.port().map(|p| p.as_u16())
    }
}

static SYS_PROXIES: Lazy<Arc<SystemProxyMap>> =
    Lazy::new(|| Arc::new(get_sys_proxies(get_from_registry())));

/// Get system proxies information.
///
/// It can only support Linux, Unix like, and windows system.  Note that it will always
/// return a HashMap, even if something runs into error when find registry information in
/// Windows system.  Note that invalid proxy url in the system setting will be ignored.
///
/// Returns:
///     System proxies information as a hashmap like
///     {"http": Url::parse("http://127.0.0.1:80"), "https": Url::parse("https://127.0.0.1:80")}
fn get_sys_proxies(
    #[cfg_attr(not(target_os = "windows"), allow(unused_variables))] registry_values: Option<
        RegistryProxyValues,
    >,
) -> SystemProxyMap {
    let proxies = get_from_environment();

    // TODO: move the following #[cfg] to `if expression` when attributes on `if` expressions allowed
    #[cfg(target_os = "windows")]
    {
        if proxies.is_empty() {
            // don't care errors if can't get proxies from registry, just return an empty HashMap.
            if let Some(registry_values) = registry_values {
                return parse_registry_values(registry_values);
            }
        }
    }
    proxies
}

fn insert_proxy(proxies: &mut SystemProxyMap, scheme: impl Into<String>, addr: String) -> bool {
    if addr.trim().is_empty() {
        // do not accept empty or whitespace proxy address
        false
    } else if let Ok(valid_addr) = addr.into_proxy_scheme() {
        proxies.insert(scheme.into(), valid_addr);
        true
    } else {
        false
    }
}

fn get_from_environment() -> SystemProxyMap {
    let mut proxies = HashMap::new();

    if is_cgi() {
        if log::log_enabled!(log::Level::Warn) && env::var_os("HTTP_PROXY").is_some() {
            log::warn!("HTTP_PROXY environment variable ignored in CGI");
        }
    } else if !insert_from_env(&mut proxies, "http", "HTTP_PROXY") {
        insert_from_env(&mut proxies, "http", "http_proxy");
    }

    if !insert_from_env(&mut proxies, "https", "HTTPS_PROXY") {
        insert_from_env(&mut proxies, "https", "https_proxy");
    }

    proxies
}

fn insert_from_env(proxies: &mut SystemProxyMap, scheme: &str, var: &str) -> bool {
    if let Ok(val) = env::var(var) {
        insert_proxy(proxies, scheme, val)
    } else {
        false
    }
}

/// Check if we are being executed in a CGI context.
///
/// If so, a malicious client can send the `Proxy:` header, and it will
/// be in the `HTTP_PROXY` env var. So we don't use it :)
fn is_cgi() -> bool {
    env::var_os("REQUEST_METHOD").is_some()
}

#[cfg(target_os = "windows")]
fn get_from_registry_impl() -> Result<RegistryProxyValues, Box<dyn Error>> {
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);
    let internet_setting: RegKey =
        hkcu.open_subkey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")?;
    // ensure the proxy is enable, if the value doesn't exist, an error will returned.
    let proxy_enable: u32 = internet_setting.get_value("ProxyEnable")?;
    let proxy_server: String = internet_setting.get_value("ProxyServer")?;

    Ok((proxy_enable, proxy_server))
}

#[cfg(target_os = "windows")]
fn get_from_registry() -> Option<RegistryProxyValues> {
    get_from_registry_impl().ok()
}

#[cfg(not(target_os = "windows"))]
fn get_from_registry() -> Option<RegistryProxyValues> {
    None
}

#[cfg(target_os = "windows")]
fn parse_registry_values_impl(
    registry_values: RegistryProxyValues,
) -> Result<SystemProxyMap, Box<dyn Error>> {
    let (proxy_enable, proxy_server) = registry_values;

    if proxy_enable == 0 {
        return Ok(HashMap::new());
    }

    let mut proxies = HashMap::new();
    if proxy_server.contains("=") {
        // per-protocol settings.
        for p in proxy_server.split(";") {
            let protocol_parts: Vec<&str> = p.split("=").collect();
            match protocol_parts.as_slice() {
                [protocol, address] => {
                    // If address doesn't specify an explicit protocol as protocol://address
                    // then default to HTTP
                    let address = if extract_type_prefix(*address).is_some() {
                        String::from(*address)
                    } else {
                        format!("http://{}", address)
                    };

                    insert_proxy(&mut proxies, *protocol, address);
                }
                _ => {
                    // Contains invalid protocol setting, just break the loop
                    // And make proxies to be empty.
                    proxies.clear();
                    break;
                }
            }
        }
    } else {
        if let Some(scheme) = extract_type_prefix(&proxy_server) {
            // Explicit protocol has been specified
            insert_proxy(&mut proxies, scheme, proxy_server.to_owned());
        } else {
            // No explicit protocol has been specified, default to HTTP
            insert_proxy(&mut proxies, "http", format!("http://{}", proxy_server));
            insert_proxy(&mut proxies, "https", format!("http://{}", proxy_server));
        }
    }
    Ok(proxies)
}

/// Extract the protocol from the given address, if present
/// For example, "https://example.com" will return Some("https")
#[cfg(target_os = "windows")]
fn extract_type_prefix(address: &str) -> Option<&str> {
    if let Some(indice) = address.find("://") {
        if indice == 0 {
            None
        } else {
            let prefix = &address[..indice];
            let contains_banned = prefix.contains(|c| c == ':' || c == '/');

            if !contains_banned {
                Some(prefix)
            } else {
                None
            }
        }
    } else {
        None
    }
}

#[cfg(target_os = "windows")]
fn parse_registry_values(registry_values: RegistryProxyValues) -> SystemProxyMap {
    parse_registry_values_impl(registry_values).unwrap_or(HashMap::new())
}

#[cfg(test)]
mod tests {
    use super::*;
    use once_cell::sync::Lazy;
    use std::sync::Mutex;

    impl Dst for Url {
        fn scheme(&self) -> &str {
            Url::scheme(self)
        }

        fn host(&self) -> &str {
            Url::host_str(self).expect("<Url as Dst>::host should have a str")
        }

        fn port(&self) -> Option<u16> {
            Url::port(self)
        }
    }

    fn url(s: &str) -> Url {
        s.parse().unwrap()
    }

    fn intercepted_uri(p: &Proxy, s: &str) -> Uri {
        let (scheme, host) = match p.intercept(&url(s)).unwrap() {
            ProxyScheme::Http { host, .. } => ("http", host),
            ProxyScheme::Https { host, .. } => ("https", host),
            #[cfg(feature = "socks")]
            _ => panic!("intercepted as socks"),
        };
        http::Uri::builder()
            .scheme(scheme)
            .authority(host)
            .path_and_query("/")
            .build()
            .expect("intercepted_uri")
    }

    #[test]
    fn test_http() {
        let target = "http://example.domain/";
        let p = Proxy::http(target).unwrap();

        let http = "http://hyper.rs";
        let other = "https://hyper.rs";

        assert_eq!(intercepted_uri(&p, http), target);
        assert!(p.intercept(&url(other)).is_none());
    }

    #[test]
    fn test_https() {
        let target = "http://example.domain/";
        let p = Proxy::https(target).unwrap();

        let http = "http://hyper.rs";
        let other = "https://hyper.rs";

        assert!(p.intercept(&url(http)).is_none());
        assert_eq!(intercepted_uri(&p, other), target);
    }

    #[test]
    fn test_all() {
        let target = "http://example.domain/";
        let p = Proxy::all(target).unwrap();

        let http = "http://hyper.rs";
        let https = "https://hyper.rs";
        let other = "x-youve-never-heard-of-me-mr-proxy://hyper.rs";

        assert_eq!(intercepted_uri(&p, http), target);
        assert_eq!(intercepted_uri(&p, https), target);
        assert_eq!(intercepted_uri(&p, other), target);
    }

    #[test]
    fn test_custom() {
        let target1 = "http://example.domain/";
        let target2 = "https://example.domain/";
        let p = Proxy::custom(move |url| {
            if url.host_str() == Some("hyper.rs") {
                target1.parse().ok()
            } else if url.scheme() == "http" {
                target2.parse().ok()
            } else {
                None::<Url>
            }
        });

        let http = "http://seanmonstar.com";
        let https = "https://hyper.rs";
        let other = "x-youve-never-heard-of-me-mr-proxy://seanmonstar.com";

        assert_eq!(intercepted_uri(&p, http), target2);
        assert_eq!(intercepted_uri(&p, https), target1);
        assert!(p.intercept(&url(other)).is_none());
    }

    #[test]
    fn test_proxy_scheme_parse() {
        let ps = "http://foo:bar@localhost:1239".into_proxy_scheme().unwrap();

        match ps {
            ProxyScheme::Http { auth, host } => {
                assert_eq!(auth.unwrap(), encode_basic_auth("foo", "bar"));
                assert_eq!(host, "localhost:1239");
            }
            other => panic!("unexpected: {:?}", other),
        }
    }

    #[test]
    fn test_proxy_scheme_ip_address_default_http() {
        let ps = "192.168.1.1:8888".into_proxy_scheme().unwrap();

        match ps {
            ProxyScheme::Http { auth, host } => {
                assert!(auth.is_none());
                assert_eq!(host, "192.168.1.1:8888");
            }
            other => panic!("unexpected: {:?}", other),
        }
    }

    #[test]
    fn test_proxy_scheme_parse_default_http_with_auth() {
        // this should fail because `foo` is interpreted as the scheme and no host can be found
        let ps = "foo:bar@localhost:1239".into_proxy_scheme().unwrap();

        match ps {
            ProxyScheme::Http { auth, host } => {
                assert_eq!(auth.unwrap(), encode_basic_auth("foo", "bar"));
                assert_eq!(host, "localhost:1239");
            }
            other => panic!("unexpected: {:?}", other),
        }
    }

    #[test]
    fn test_domain_matcher() {
        let domains = vec![".foo.bar".into(), "bar.foo".into()];
        let matcher = DomainMatcher(domains);

        // domains match with leading `.`
        assert!(matcher.contains("foo.bar"));
        // subdomains match with leading `.`
        assert!(matcher.contains("www.foo.bar"));

        // domains match with no leading `.`
        assert!(matcher.contains("bar.foo"));
        // subdomains match with no leading `.`
        assert!(matcher.contains("www.bar.foo"));

        // non-subdomain string prefixes don't match
        assert!(!matcher.contains("notfoo.bar"));
        assert!(!matcher.contains("notbar.foo"));
    }

    // Smallest possible content for a mutex
    struct MutexInner;

    static ENVLOCK: Lazy<Mutex<MutexInner>> = Lazy::new(|| Mutex::new(MutexInner));

    #[test]
    fn test_get_sys_proxies_parsing() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("HTTP_PROXY");
        let _g2 = env_guard("http_proxy");

        // Mock ENV, get the results, before doing assertions
        // to avoid assert! -> panic! -> Mutex Poisoned.
        let baseline_proxies = get_sys_proxies(None);
        // the system proxy setting url is invalid.
        env::set_var("http_proxy", "file://123465");
        let invalid_proxies = get_sys_proxies(None);
        // set valid proxy
        env::set_var("http_proxy", "127.0.0.1/");
        let valid_proxies = get_sys_proxies(None);

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);

        assert!(!baseline_proxies.contains_key("http"));
        assert!(!invalid_proxies.contains_key("http"));

        let p = &valid_proxies["http"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1");
    }

    #[cfg(target_os = "windows")]
    #[test]
    fn test_get_sys_proxies_registry_parsing() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("HTTP_PROXY");
        let _g2 = env_guard("http_proxy");

        // Mock ENV, get the results, before doing assertions
        // to avoid assert! -> panic! -> Mutex Poisoned.
        let baseline_proxies = get_sys_proxies(None);
        // the system proxy in the registry has been disabled
        let disabled_proxies = get_sys_proxies(Some((0, String::from("http://127.0.0.1/"))));
        // set valid proxy
        let valid_proxies = get_sys_proxies(Some((1, String::from("http://127.0.0.1/"))));
        let valid_proxies_no_scheme = get_sys_proxies(Some((1, String::from("127.0.0.1"))));
        let valid_proxies_explicit_https =
            get_sys_proxies(Some((1, String::from("https://127.0.0.1/"))));
        let multiple_proxies = get_sys_proxies(Some((
            1,
            String::from("http=127.0.0.1:8888;https=127.0.0.2:8888"),
        )));
        let multiple_proxies_explicit_scheme = get_sys_proxies(Some((
            1,
            String::from("http=http://127.0.0.1:8888;https=https://127.0.0.2:8888"),
        )));

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);

        assert_eq!(baseline_proxies.contains_key("http"), false);
        assert_eq!(disabled_proxies.contains_key("http"), false);

        let p = &valid_proxies["http"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1");

        let p = &valid_proxies_no_scheme["http"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1");

        let p = &valid_proxies_no_scheme["https"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1");

        let p = &valid_proxies_explicit_https["https"];
        assert_eq!(p.scheme(), "https");
        assert_eq!(p.host(), "127.0.0.1");

        let p = &multiple_proxies["http"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1:8888");

        let p = &multiple_proxies["https"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.2:8888");

        let p = &multiple_proxies_explicit_scheme["http"];
        assert_eq!(p.scheme(), "http");
        assert_eq!(p.host(), "127.0.0.1:8888");

        let p = &multiple_proxies_explicit_scheme["https"];
        assert_eq!(p.scheme(), "https");
        assert_eq!(p.host(), "127.0.0.2:8888");
    }

    #[test]
    fn test_get_sys_proxies_in_cgi() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("REQUEST_METHOD");
        let _g2 = env_guard("HTTP_PROXY");

        // Mock ENV, get the results, before doing assertions
        // to avoid assert! -> panic! -> Mutex Poisoned.
        env::set_var("HTTP_PROXY", "http://evil/");

        let baseline_proxies = get_sys_proxies(None);
        // set like we're in CGI
        env::set_var("REQUEST_METHOD", "GET");

        let cgi_proxies = get_sys_proxies(None);

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);

        // not in CGI yet
        assert_eq!(baseline_proxies["http"].host(), "evil");
        // In CGI
        assert!(!cgi_proxies.contains_key("http"));
    }

    #[test]
    fn test_sys_no_proxy() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("HTTP_PROXY");
        let _g2 = env_guard("NO_PROXY");

        let target = "http://example.domain/";
        env::set_var("HTTP_PROXY", target);

        env::set_var(
            "NO_PROXY",
            ".foo.bar, bar.baz,10.42.1.1/24,::1,10.124.7.8,2001::/17",
        );

        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();

        // random url, not in no_proxy
        assert_eq!(intercepted_uri(&p, "http://hyper.rs"), target);
        // make sure that random non-subdomain string prefixes don't match
        assert_eq!(intercepted_uri(&p, "http://notfoo.bar"), target);
        // make sure that random non-subdomain string prefixes don't match
        assert_eq!(intercepted_uri(&p, "http://notbar.baz"), target);
        // ipv4 address out of range
        assert_eq!(intercepted_uri(&p, "http://10.43.1.1"), target);
        // ipv4 address out of range
        assert_eq!(intercepted_uri(&p, "http://10.124.7.7"), target);
        // ipv6 address out of range
        assert_eq!(intercepted_uri(&p, "http://[ffff:db8:a0b:12f0::1]"), target);
        // ipv6 address out of range
        assert_eq!(intercepted_uri(&p, "http://[2005:db8:a0b:12f0::1]"), target);

        // make sure subdomains (with leading .) match
        assert!(p.intercept(&url("http://hello.foo.bar")).is_none());
        // make sure exact matches (without leading .) match (also makes sure spaces between entries work)
        assert!(p.intercept(&url("http://bar.baz")).is_none());
        // check case sensitivity
        assert!(p.intercept(&url("http://BAR.baz")).is_none());
        // make sure subdomains (without leading . in no_proxy) match
        assert!(p.intercept(&url("http://foo.bar.baz")).is_none());
        // make sure subdomains (without leading . in no_proxy) match - this differs from cURL
        assert!(p.intercept(&url("http://foo.bar")).is_none());
        // ipv4 address match within range
        assert!(p.intercept(&url("http://10.42.1.100")).is_none());
        // ipv6 address exact match
        assert!(p.intercept(&url("http://[::1]")).is_none());
        // ipv6 address match within range
        assert!(p.intercept(&url("http://[2001:db8:a0b:12f0::1]")).is_none());
        // ipv4 address exact match
        assert!(p.intercept(&url("http://10.124.7.8")).is_none());

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);
    }

    #[test]
    fn test_proxy_no_proxy_interception_for_proxy_types() {
        let proxy_url = "http://example.domain/";
        let no_proxy = ".no.proxy.tld";

        // test all proxy interception
        let p = Proxy::all(proxy_url)
            .unwrap()
            .no_proxy(NoProxy::from_string(no_proxy));

        // random url, not in no_proxy
        assert_eq!(intercepted_uri(&p, "http://hyper.rs"), proxy_url);

        // positive match for no proxy
        assert!(p.intercept(&url("https://hello.no.proxy.tld")).is_none());

        // test http proxy interception
        let p = Proxy::http(proxy_url)
            .unwrap()
            .no_proxy(NoProxy::from_string(no_proxy));

        // random url, not in no_proxy
        assert_eq!(intercepted_uri(&p, "http://hyper.rs"), proxy_url);

        // positive match for no proxy
        assert!(p.intercept(&url("http://hello.no.proxy.tld")).is_none());

        // should not be intercepted due to scheme
        assert!(p.intercept(&url("https://hyper.rs")).is_none());

        // test https proxy interception
        let p = Proxy::https(proxy_url)
            .unwrap()
            .no_proxy(NoProxy::from_string(no_proxy));

        // random url, not in no_proxy
        assert_eq!(intercepted_uri(&p, "https://hyper.rs"), proxy_url);

        // positive match for no proxy
        assert!(p.intercept(&url("https://hello.no.proxy.tld")).is_none());

        // should not be intercepted due to scheme
        assert!(p.intercept(&url("http://hyper.rs")).is_none());

        // test custom proxy interception
        let p = Proxy::custom(move |_url| Some(proxy_url)).no_proxy(NoProxy::from_string(no_proxy));

        // random url, not in no_proxy
        assert_eq!(intercepted_uri(&p, "https://hyper.rs"), proxy_url);

        // positive match for no proxy
        assert!(p.intercept(&url("https://hello.no.proxy.tld")).is_none());
        assert!(p.intercept(&url("http://hello.no.proxy.tld")).is_none());
    }

    #[test]
    fn test_wildcard_sys_no_proxy() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("HTTP_PROXY");
        let _g2 = env_guard("NO_PROXY");

        let target = "http://example.domain/";
        env::set_var("HTTP_PROXY", target);

        env::set_var("NO_PROXY", "*");

        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();

        assert!(p.intercept(&url("http://foo.bar")).is_none());

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);
    }

    #[test]
    fn test_empty_sys_no_proxy() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();
        // save system setting first.
        let _g1 = env_guard("HTTP_PROXY");
        let _g2 = env_guard("NO_PROXY");

        let target = "http://example.domain/";
        env::set_var("HTTP_PROXY", target);

        env::set_var("NO_PROXY", ",");

        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();

        // everything should go through proxy, "effectively" nothing is in no_proxy
        assert_eq!(intercepted_uri(&p, "http://hyper.rs"), target);

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        // Let other threads run now
        drop(_lock);
    }

    #[test]
    fn test_no_proxy_load() {
        // Stop other threads from modifying process-global ENV while we are.
        let _lock = ENVLOCK.lock();

        let _g1 = env_guard("no_proxy");
        let domain = "lower.case";
        env::set_var("no_proxy", domain);
        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();
        assert_eq!(
            p.no_proxy.expect("should have a no proxy set").domains.0[0],
            domain
        );

        env::remove_var("no_proxy");
        let _g2 = env_guard("NO_PROXY");
        let domain = "upper.case";
        env::set_var("NO_PROXY", domain);
        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();
        assert_eq!(
            p.no_proxy.expect("should have a no proxy set").domains.0[0],
            domain
        );

        let _g3 = env_guard("HTTP_PROXY");
        env::remove_var("NO_PROXY");
        env::remove_var("no_proxy");
        let target = "http://example.domain/";
        env::set_var("HTTP_PROXY", target);

        // Manually construct this so we aren't use the cache
        let mut p = Proxy::new(Intercept::System(Arc::new(get_sys_proxies(None))));
        p.no_proxy = NoProxy::from_env();
        assert!(p.no_proxy.is_none(), "NoProxy shouldn't have been created");

        assert_eq!(intercepted_uri(&p, "http://hyper.rs"), target);

        // reset user setting when guards drop
        drop(_g1);
        drop(_g2);
        drop(_g3);
        // Let other threads run now
        drop(_lock);
    }

    #[cfg(target_os = "windows")]
    #[test]
    fn test_type_prefix_extraction() {
        assert!(extract_type_prefix("test").is_none());
        assert!(extract_type_prefix("://test").is_none());
        assert!(extract_type_prefix("some:prefix://test").is_none());
        assert!(extract_type_prefix("some/prefix://test").is_none());

        assert_eq!(extract_type_prefix("http://test").unwrap(), "http");
        assert_eq!(extract_type_prefix("a://test").unwrap(), "a");
    }

    /// Guard an environment variable, resetting it to the original value
    /// when dropped.
    fn env_guard(name: impl Into<String>) -> EnvGuard {
        let name = name.into();
        let orig_val = env::var(&name).ok();
        env::remove_var(&name);
        EnvGuard { name, orig_val }
    }

    struct EnvGuard {
        name: String,
        orig_val: Option<String>,
    }

    impl Drop for EnvGuard {
        fn drop(&mut self) {
            if let Some(val) = self.orig_val.take() {
                env::set_var(&self.name, val);
            } else {
                env::remove_var(&self.name);
            }
        }
    }

    #[test]
    fn test_has_http_auth() {
        let http_proxy_with_auth = Proxy {
            intercept: Intercept::Http(ProxyScheme::Http {
                auth: Some(HeaderValue::from_static("auth1")),
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(http_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            http_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            Some(HeaderValue::from_static("auth1"))
        );

        let http_proxy_without_auth = Proxy {
            intercept: Intercept::Http(ProxyScheme::Http {
                auth: None,
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(!http_proxy_without_auth.maybe_has_http_auth());
        assert_eq!(
            http_proxy_without_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            None
        );

        let https_proxy_with_auth = Proxy {
            intercept: Intercept::Http(ProxyScheme::Https {
                auth: Some(HeaderValue::from_static("auth2")),
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(https_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            https_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            Some(HeaderValue::from_static("auth2"))
        );

        let all_http_proxy_with_auth = Proxy {
            intercept: Intercept::All(ProxyScheme::Http {
                auth: Some(HeaderValue::from_static("auth3")),
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(all_http_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            all_http_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            Some(HeaderValue::from_static("auth3"))
        );

        let all_https_proxy_with_auth = Proxy {
            intercept: Intercept::All(ProxyScheme::Https {
                auth: Some(HeaderValue::from_static("auth4")),
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(all_https_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            all_https_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            Some(HeaderValue::from_static("auth4"))
        );

        let all_https_proxy_without_auth = Proxy {
            intercept: Intercept::All(ProxyScheme::Https {
                auth: None,
                host: http::uri::Authority::from_static("authority"),
            }),
            no_proxy: None,
        };
        assert!(!all_https_proxy_without_auth.maybe_has_http_auth());
        assert_eq!(
            all_https_proxy_without_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            None
        );

        let system_http_proxy_with_auth = Proxy {
            intercept: Intercept::System(Arc::new({
                let mut m = HashMap::new();
                m.insert(
                    "http".into(),
                    ProxyScheme::Http {
                        auth: Some(HeaderValue::from_static("auth5")),
                        host: http::uri::Authority::from_static("authority"),
                    },
                );
                m
            })),
            no_proxy: None,
        };
        assert!(system_http_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            system_http_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            Some(HeaderValue::from_static("auth5"))
        );

        let system_https_proxy_with_auth = Proxy {
            intercept: Intercept::System(Arc::new({
                let mut m = HashMap::new();
                m.insert(
                    "https".into(),
                    ProxyScheme::Https {
                        auth: Some(HeaderValue::from_static("auth6")),
                        host: http::uri::Authority::from_static("authority"),
                    },
                );
                m
            })),
            no_proxy: None,
        };
        assert!(!system_https_proxy_with_auth.maybe_has_http_auth());
        assert_eq!(
            system_https_proxy_with_auth.http_basic_auth(&Uri::from_static("http://example.com")),
            None
        );
    }
}

#[cfg(test)]
mod test {
    mod into_proxy_scheme {
        use crate::Proxy;
        use std::error::Error;
        use std::mem::discriminant;

        fn includes(haystack: &crate::error::Error, needle: url::ParseError) -> bool {
            let mut source = haystack.source();
            while let Some(error) = source {
                if let Some(parse_error) = error.downcast_ref::<url::ParseError>() {
                    if discriminant(parse_error) == discriminant(&needle) {
                        return true;
                    }
                }
                source = error.source();
            }
            false
        }

        fn check_parse_error(url: &str, needle: url::ParseError) {
            let error = Proxy::http(url).unwrap_err();
            if !includes(&error, needle) {
                panic!("{:?} expected; {:?}, {} found", needle, error, error);
            }
        }

        mod when_scheme_missing {
            mod and_url_is_valid {
                use crate::Proxy;

                #[test]
                fn lookback_works() {
                    let _ = Proxy::http("127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_port_works() {
                    let _ = Proxy::http("127.0.0.1:8080").unwrap();
                }

                #[test]
                fn loopback_username_works() {
                    let _ = Proxy::http("username@127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_username_password_works() {
                    let _ = Proxy::http("username:password@127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_username_password_port_works() {
                    let _ = Proxy::http("ldap%5Cgremlin:pass%3Bword@127.0.0.1:8080").unwrap();
                }

                #[test]
                fn domain_works() {
                    let _ = Proxy::http("proxy.example.com").unwrap();
                }

                #[test]
                fn domain_port_works() {
                    let _ = Proxy::http("proxy.example.com:8080").unwrap();
                }

                #[test]
                fn domain_username_works() {
                    let _ = Proxy::http("username@proxy.example.com").unwrap();
                }

                #[test]
                fn domain_username_password_works() {
                    let _ = Proxy::http("username:password@proxy.example.com").unwrap();
                }

                #[test]
                fn domain_username_password_port_works() {
                    let _ =
                        Proxy::http("ldap%5Cgremlin:pass%3Bword@proxy.example.com:8080").unwrap();
                }
            }
            mod and_url_has_bad {
                use super::super::check_parse_error;

                #[test]
                fn host() {
                    check_parse_error("username@", url::ParseError::RelativeUrlWithoutBase);
                }

                #[test]
                fn idna_encoding() {
                    check_parse_error("xn---", url::ParseError::RelativeUrlWithoutBase);
                }

                #[test]
                fn port() {
                    check_parse_error("127.0.0.1:808080", url::ParseError::RelativeUrlWithoutBase);
                }

                #[test]
                fn ip_v4_address() {
                    check_parse_error("421.627.718.469", url::ParseError::RelativeUrlWithoutBase);
                }

                #[test]
                fn ip_v6_address() {
                    check_parse_error(
                        "[56FE::2159:5BBC::6594]",
                        url::ParseError::RelativeUrlWithoutBase,
                    );
                }

                #[test]
                fn invalid_domain_character() {
                    check_parse_error("abc 123", url::ParseError::RelativeUrlWithoutBase);
                }
            }
        }

        mod when_scheme_present {
            mod and_url_is_valid {
                use crate::Proxy;

                #[test]
                fn loopback_works() {
                    let _ = Proxy::http("http://127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_port_works() {
                    let _ = Proxy::http("https://127.0.0.1:8080").unwrap();
                }

                #[test]
                fn loopback_username_works() {
                    let _ = Proxy::http("http://username@127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_username_password_works() {
                    let _ = Proxy::http("https://username:password@127.0.0.1").unwrap();
                }

                #[test]
                fn loopback_username_password_port_works() {
                    let _ =
                        Proxy::http("http://ldap%5Cgremlin:pass%3Bword@127.0.0.1:8080").unwrap();
                }

                #[test]
                fn domain_works() {
                    let _ = Proxy::http("https://proxy.example.com").unwrap();
                }

                #[test]
                fn domain_port_works() {
                    let _ = Proxy::http("http://proxy.example.com:8080").unwrap();
                }

                #[test]
                fn domain_username_works() {
                    let _ = Proxy::http("https://username@proxy.example.com").unwrap();
                }

                #[test]
                fn domain_username_password_works() {
                    let _ = Proxy::http("http://username:password@proxy.example.com").unwrap();
                }

                #[test]
                fn domain_username_password_port_works() {
                    let _ =
                        Proxy::http("https://ldap%5Cgremlin:pass%3Bword@proxy.example.com:8080")
                            .unwrap();
                }
            }
            mod and_url_has_bad {
                use super::super::check_parse_error;

                #[test]
                fn host() {
                    check_parse_error("http://username@", url::ParseError::EmptyHost);
                }

                #[test]
                fn idna_encoding() {
                    check_parse_error("http://xn---", url::ParseError::IdnaError);
                }

                #[test]
                fn port() {
                    check_parse_error("http://127.0.0.1:808080", url::ParseError::InvalidPort);
                }

                #[test]
                fn ip_v4_address() {
                    check_parse_error(
                        "http://421.627.718.469",
                        url::ParseError::InvalidIpv4Address,
                    );
                }

                #[test]
                fn ip_v6_address() {
                    check_parse_error(
                        "http://[56FE::2159:5BBC::6594]",
                        url::ParseError::InvalidIpv6Address,
                    );
                }

                #[test]
                fn invalid_domain_character() {
                    check_parse_error("http://abc 123/", url::ParseError::InvalidDomainCharacter);
                }
            }
        }
    }
}
