// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Provides the command "wireguard" for crosh which can configure and control a WireGuard service
// in Shill.

use std::{collections::HashMap, io};

use dbus::{
    self,
    arg::{ArgType, RefArg, Variant},
    blocking::Connection,
};
use sys_util::error;
use system_api::client::OrgChromiumFlimflamManager;
use system_api::client::OrgChromiumFlimflamService;

use crate::{
    dispatcher::{self, Arguments, Command, Dispatcher},
    util::{is_consumer_device, DEFAULT_DBUS_TIMEOUT},
};

const USAGE: &str = r#"wireguard <cmd> [<args>]

Available subcommands:

list
    Show all configured WireGuard services.
show <name>
    Show the WireGuard service with name <name>.
new <name>
    Create a new WireGuard service with name <name>.
del <name>
    Delete the configured WireGuard service with name <name>.
set <name> [local-ip <ip>] [private-key] [mtu <mtu>] [dns <ip1>[,<ip2>]...]
           [peer <base64-public-key> [remove]
                                     [endpoint <hostname>/<ip>:<port>]
                                     [preshared-key]
                                     [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...]
                                     [persistent-keepalive <interval seconds>] ]...
    Configure properties for the WireGuard service with name <name>. Most options should
    have the same meaning and usage as in `wireguard-tools` (and `wg-quick`). Exceptions
    are:
    - Only IPv4 is supported for the VPN overlay, so `local-ip`, `dns`, and `allowed-ips`
      should be set to IPv4 address(es).
    - If `dns` is not set, it will be defaulted to "8.8.8.8,8.8.4.4".
    - If `mtu` is not set, it will be determined automatically. Set it to 0 to reset the
      existing value.
    - `endpoint` must be set before using `connect` command.
    - `private-key` and `preshared-key` take no parameters. If they are used, this command
      will prompt you to change the key (or remove the key) via stdin, to avoid leaving
      them in the history of shell.
connect <name>
    Connect to the configured WireGuard service with name <name>.
disconnect <name>
    Disconnect from the configured WireGuard service with name <name>.
"#;

pub fn register(dispatcher: &mut Dispatcher) {
    if let Ok(true) = is_consumer_device() {
        dispatcher.register_command(
            Command::new(
                "wireguard".to_string(),
                USAGE.to_string(),
                "Utility to configure and control a WireGuard VPN service".to_string(),
            )
            .set_command_callback(Some(execute_wireguard)),
        );
    }
}

#[derive(Debug)]
enum Error {
    InvalidArguments(String),
    ServiceNotFound(String),
    ServiceAlreadyExists(String),
    ServiceNotConnectable {
        service_name: String,
        reason: String,
    },
    VpnDisabled,
    WireGuardUnavailable,
    Internal(String),
}

fn execute_wireguard(_cmd: &Command, args: &Arguments) -> Result<(), dispatcher::Error> {
    let convert_err = |err: Error| match err {
        Error::InvalidArguments(val) => dispatcher::Error::CommandInvalidArguments(val),
        Error::ServiceNotFound(val) => {
            println!("WireGuard service with name {} does not exist", val);
            dispatcher::Error::CommandReturnedError
        }
        Error::ServiceAlreadyExists(val) => {
            println!("WireGuard service with name {} already exists", val);
            dispatcher::Error::CommandReturnedError
        }
        Error::ServiceNotConnectable {
            service_name,
            reason,
        } => {
            println!(
                "WireGuard service with name {} is not connectable: {}",
                service_name, reason
            );
            dispatcher::Error::CommandReturnedError
        }
        Error::VpnDisabled => {
            println!("VPN is disabled on this device");
            dispatcher::Error::CommandReturnedError
        }
        Error::WireGuardUnavailable => {
            println!("WireGuard is not available on this device");
            dispatcher::Error::CommandReturnedError
        }
        Error::Internal(val) => {
            error!("ERROR: {}", val);
            dispatcher::Error::CommandReturnedError
        }
    };

    check_wireguard_support().map_err(convert_err)?;

    let args: Vec<&str> = args.get_args().iter().map(String::as_str).collect();
    match args.as_slice() {
        [] => Err(Error::InvalidArguments("no command".to_string())),
        ["show"] | ["list"] => wireguard_list(),
        ["show", service_name] => wireguard_show(service_name),
        ["new", service_name] => wireguard_new(service_name),
        ["del", service_name] => wireguard_del(service_name),
        ["set", service_name, remaining @ ..] => wireguard_set(service_name, remaining),
        ["connect", service_name] => wireguard_connect(service_name),
        ["disconnect", service_name] => wireguard_disconnect(service_name),
        [other, ..] => Err(Error::InvalidArguments(other.to_string())),
    }
    .map_err(convert_err)
}

// Represents the properties returned by GetProperties method from D-Bus.
type InputPropMap = HashMap<String, Variant<Box<dyn RefArg>>>;
// Represents the properties nested as a value of another property in the InputPropMap.
type InnerPropMap<'a> = HashMap<&'a str, &'a dyn RefArg>;
// Represents the properties used to configure a service via D-Bus.
type OutputPropMap = HashMap<&'static str, Variant<Box<dyn RefArg>>>;

// Helper functions for reading a value with a specific type from a property map.
trait GetPropExt {
    fn get_arg(&self, key: &str) -> Result<&dyn RefArg, Error>;

    fn get_str(&self, key: &str) -> Result<&str, Error> {
        self.get_arg(key)?
            .as_str()
            .ok_or_else(|| get_prop_error(key, "str"))
    }

    fn get_string(&self, key: &str) -> Result<String, Error> {
        Ok(self.get_str(key)?.to_string())
    }

    fn get_i32(&self, key: &str) -> Result<i32, Error> {
        self.get_arg(key)?
            .as_i64()
            .map(|x| x as i32)
            .ok_or_else(|| get_prop_error(key, "i32"))
    }

    fn get_strings(&self, key: &str) -> Result<Vec<String>, Error> {
        self.get_arg(key)?
            .as_iter()
            .ok_or_else(|| get_prop_error(key, "vec"))?
            .map(|arg| {
                arg.as_str()
                    .ok_or_else(|| get_prop_error(key, "str"))
                    .map(|x| x.to_string())
            })
            .collect()
    }

    fn get_inner_prop_map(&self, key: &str) -> Result<InnerPropMap, Error> {
        parse_arg_to_map(self.get_arg(key)?).ok_or_else(|| get_prop_error(key, "map"))
    }

    fn get_inner_prop_maps(&self, key: &str) -> Result<Vec<InnerPropMap>, Error> {
        self.get_arg(key)?
            .as_iter()
            .ok_or_else(|| get_prop_error(key, "vec"))?
            .map(|arg| parse_arg_to_map(arg).ok_or_else(|| get_prop_error(key, "map")))
            .collect()
    }
}

fn get_prop_error(k: &str, t: &str) -> Error {
    Error::Internal(format!("Failed to parse properties {} with type {}", k, t))
}

fn parse_arg_to_map(arg: &dyn RefArg) -> Option<InnerPropMap> {
    let mut kvs = HashMap::new();
    let mut itr = arg.as_iter()?;
    while let Some(val) = itr.next() {
        let key = val.as_str()?;
        let next = itr.next()?;
        // Unwraps it if the value type is Variant, since it may affect iterating over the inner
        // value if the inner type is dict.
        if next.arg_type() == ArgType::Variant {
            let mut inner_itr = next.as_iter().unwrap();
            kvs.insert(key, inner_itr.next().unwrap());
        } else {
            kvs.insert(key, next);
        }
    }
    Some(kvs)
}

impl GetPropExt for InputPropMap {
    fn get_arg(&self, key: &str) -> Result<&dyn RefArg, Error> {
        Ok(&self
            .get(&key.to_string())
            .ok_or_else(|| get_prop_error(key, "ref_arg"))?
            .0)
    }
}

impl GetPropExt for InnerPropMap<'_> {
    fn get_arg(&self, key: &str) -> Result<&dyn RefArg, Error> {
        Ok(self
            .get(key)
            .ok_or_else(|| get_prop_error(key, "ref_arg"))?)
    }
}

// The following constants are defined in system_api/dbus/shill/dbus-constants.h.
// Also see shill/doc/manager-api.txt and shill/doc/service-api.txt for their meanings.

// Property names for manager.
const PROPERTY_PROHIBITED_TECHNOLOGIES: &str = "ProhibitedTechnologies";
const PROPERTY_SERVICES: &str = "Services";
const PROPERTY_SUPPORTED_VPN_TYPES: &str = "SupportedVPNTypes";

// Property names for service.
const PROPERTY_TYPE: &str = "Type";
const PROPERTY_NAME: &str = "Name";
const PROPERTY_PROVIDER_TYPE: &str = "Provider.Type";
const PROPERTY_PROVIDER_HOST: &str = "Provider.Host";
const PROPERTY_WIREGUARD_PRIVATE_KEY: &str = "WireGuard.PrivateKey";
const PROPERTY_WIREGUARD_PUBLIC_KEY: &str = "WireGuard.PublicKey";
const PROPERTY_WIREGUARD_PEERS: &str = "WireGuard.Peers";
const PROPERTY_STATIC_IP_CONFIG: &str = "StaticIPConfig";
const PROPERTY_SAVE_CREDENTIALS: &str = "SaveCredentials";

// Property names for WireGuard in "WireGuard.Peers".
const PROPERTY_PEER_PUBLIC_KEY: &str = "PublicKey";
const PROPERTY_PEER_PRESHARED_KEY: &str = "PresharedKey";
const PROPERTY_PEER_ENDPOINT: &str = "Endpoint";
const PROPERTY_PEER_ALLOWED_IPS: &str = "AllowedIPs";
const PROPERTY_PEER_PERSISTENT_KEEPALIVE: &str = "PersistentKeepalive";

// Property names in "StaticIPConfig"
const PROPERTY_ADDRESS: &str = "Address";
const PROPERTY_NAME_SERVERS: &str = "NameServers";
const PROPERTY_MTU: &str = "Mtu";

// Property values.
const TYPE_VPN: &str = "vpn";
const TYPE_WIREGUARD: &str = "wireguard";

// Represents a WireGuard service in Shill.
#[derive(Clone, Debug, PartialEq)]
struct WireGuardService {
    path: Option<String>,
    name: String,
    local_ip: Option<String>,
    private_key: Option<String>,
    public_key: String,
    mtu: Option<i32>,
    name_servers: Option<Vec<String>>,
    peers: Vec<WireGuardPeer>,
}

#[derive(Clone, Debug, PartialEq)]
struct WireGuardPeer {
    public_key: String,
    endpoint: String,
    allowed_ips: String,
    persistent_keepalive: String,
    preshared_key: Option<String>,
}

impl WireGuardService {
    fn parse_from_prop_map(service_properties: &InputPropMap) -> Result<Self, Error> {
        let service_name = service_properties.get_str(PROPERTY_NAME)?;

        let not_wg_service_err =
            Error::ServiceNotFound(format!("{} is not a WireGuard VPN service", service_name));

        let service_type = service_properties.get_str(PROPERTY_TYPE)?;
        if service_type != TYPE_VPN {
            return Err(not_wg_service_err);
        }

        // Reads address, dns servers, and mtu from StaticIPConfig. This property and all the
        // sub-properties could be empty.
        let mut local_ip = None;
        let mut mtu = None;
        let mut name_servers = None;
        if let Ok(props) = service_properties.get_inner_prop_map(PROPERTY_STATIC_IP_CONFIG) {
            // Note that the ok() below may potentially ignore some real parsing failures. It
            // should not happen if shill is working correctly so we use ok() here for simplicity.
            local_ip = props.get_string(PROPERTY_ADDRESS).ok();
            name_servers = props.get_strings(PROPERTY_NAME_SERVERS).ok();
            mtu = props.get_i32(PROPERTY_MTU).ok();
        }

        // The value of the "Provider" property is a map. Translates it into a HashMap at first.
        let provider_properties = service_properties.get_inner_prop_map("Provider")?;

        if provider_properties.get_str(PROPERTY_TYPE)? != TYPE_WIREGUARD {
            return Err(not_wg_service_err);
        }

        let ret = WireGuardService {
            path: None,
            name: service_name.to_string(),
            local_ip,
            private_key: None,
            public_key: provider_properties.get_string(PROPERTY_WIREGUARD_PUBLIC_KEY)?,
            mtu,
            name_servers,
            peers: provider_properties
                .get_inner_prop_maps(PROPERTY_WIREGUARD_PEERS)?
                .into_iter()
                .map(|p| {
                    Ok(WireGuardPeer {
                        public_key: p.get_string(PROPERTY_PEER_PUBLIC_KEY)?,
                        endpoint: p.get_string(PROPERTY_PEER_ENDPOINT)?,
                        allowed_ips: p.get_string(PROPERTY_PEER_ALLOWED_IPS)?,
                        persistent_keepalive: p.get_string(PROPERTY_PEER_PERSISTENT_KEEPALIVE)?,
                        preshared_key: None,
                    })
                })
                .collect::<Result<Vec<WireGuardPeer>, Error>>()?,
        };

        Ok(ret)
    }

    fn encode_into_prop_map(&self) -> OutputPropMap {
        let mut properties: OutputPropMap = HashMap::new();
        let mut insert_string_field = |k: &'static str, v: &str| {
            properties.insert(k, Variant(Box::new(v.to_string())));
        };

        insert_string_field(PROPERTY_TYPE, TYPE_VPN);
        insert_string_field(PROPERTY_NAME, &self.name);
        insert_string_field(PROPERTY_PROVIDER_TYPE, TYPE_WIREGUARD);
        insert_string_field(PROPERTY_PROVIDER_HOST, TYPE_WIREGUARD);
        if let Some(val) = &self.private_key {
            insert_string_field(PROPERTY_WIREGUARD_PRIVATE_KEY, val);
        }

        let mut static_ip_properties = HashMap::new();
        let mut insert_ip_field = |k: &str, v: Box<dyn RefArg>| {
            static_ip_properties.insert(k.to_string(), Variant(v));
        };
        if let Some(local_ip) = &self.local_ip {
            insert_ip_field(PROPERTY_ADDRESS, Box::new(local_ip.clone()));
        }
        if let Some(name_servers) = &self.name_servers {
            insert_ip_field(PROPERTY_NAME_SERVERS, Box::new(name_servers.clone()));
        } else {
            insert_ip_field(
                PROPERTY_NAME_SERVERS,
                Box::new(vec!["8.8.8.8".to_string(), "8.8.4.4".to_string()]),
            );
        }
        if let Some(mtu) = self.mtu {
            insert_ip_field(PROPERTY_MTU, Box::new(mtu));
        }
        if !static_ip_properties.is_empty() {
            properties.insert(
                PROPERTY_STATIC_IP_CONFIG,
                Variant(Box::new(static_ip_properties)),
            );
        }

        let mut peers_buf = Vec::new();
        for peer in &self.peers {
            let mut peer_properties = HashMap::new();
            let mut insert_peer_field = |k: &str, v: &str| {
                peer_properties.insert(k.to_string(), v.to_string());
            };
            insert_peer_field(PROPERTY_PEER_PUBLIC_KEY, &peer.public_key);
            insert_peer_field(PROPERTY_PEER_ENDPOINT, &peer.endpoint);
            insert_peer_field(PROPERTY_PEER_ALLOWED_IPS, &peer.allowed_ips);
            insert_peer_field(
                PROPERTY_PEER_PERSISTENT_KEEPALIVE,
                &peer.persistent_keepalive,
            );
            if let Some(val) = &peer.preshared_key {
                insert_peer_field(PROPERTY_PEER_PRESHARED_KEY, val);
            }
            peers_buf.push(peer_properties);
        }
        properties.insert(PROPERTY_WIREGUARD_PEERS, Variant(Box::new(peers_buf)));

        // Always persists keys.
        properties.insert(PROPERTY_SAVE_CREDENTIALS, Variant(Box::new(true)));

        properties
    }

    // Updates the service by |args| from `wireguard set` command. If `private-key` or
    // `preshared-key` is specified, keys will be read from |reader|, which is usually stdin.
    fn update_from_args<R: io::BufRead>(
        &mut self,
        args: &[&str],
        mut reader: R,
    ) -> Result<(), Error> {
        use option_util::*;

        // May point to a peer in |self.peers| which is being processed currently.
        let mut current_peer = None;
        // Indicates if |current_peer| is a peer added in this command.
        let mut is_new_peer = false;

        let mut iter = args.iter();
        while let Some(key) = iter.next() {
            let no_peer_err = Error::InvalidArguments(format!(
                "Option '{}' should appear after a peer is specified",
                key
            ));

            // Forwards the iterator to read the value for the currently processing option.
            let mut get_next_as_val = || {
                iter.next().ok_or_else(|| {
                    Error::InvalidArguments(format!(
                        "Option '{}' expects one parameter but none is given",
                        key
                    ))
                })
            };

            match *key {
                "local-ip" => self.local_ip = Some(parse_local_ip(get_next_as_val()?)?),
                "dns" => self.name_servers = parse_dns(get_next_as_val()?)?,
                "mtu" => self.mtu = parse_mtu(get_next_as_val()?)?,
                "private-key" => {
                    let lines = [
                        "Change private key for this service (or press <Enter> directly",
                        "to let the system generate a random key).",
                        "New key: ",
                    ];
                    let prompt = lines.join("\n");
                    self.private_key = Some(read_key(&prompt, &mut reader)?);
                }
                "peer" => {
                    let pubkey = parse_peer(get_next_as_val()?)?;
                    current_peer = self.peers.iter_mut().find(|x| x.public_key == pubkey);
                    is_new_peer = current_peer.is_none();
                    if is_new_peer {
                        self.peers.push(WireGuardPeer {
                            public_key: pubkey,
                            endpoint: "".to_string(),
                            allowed_ips: "".to_string(),
                            persistent_keepalive: "".to_string(),
                            preshared_key: None,
                        });
                        current_peer = self.peers.last_mut();
                    }
                }
                "remove" => {
                    if is_new_peer {
                        return Err(Error::InvalidArguments(
                            "Peer to be removed does not exist".to_string(),
                        ));
                    }
                    let pubkey = current_peer.as_mut().ok_or(no_peer_err)?.public_key.clone();
                    current_peer = None;
                    self.peers.retain(|x| x.public_key != pubkey);
                }
                "endpoint" => {
                    current_peer.as_mut().ok_or(no_peer_err)?.endpoint =
                        parse_endpoint(get_next_as_val()?)?;
                }
                "allowed-ips" => {
                    current_peer.as_mut().ok_or(no_peer_err)?.allowed_ips =
                        parse_allowed_ips(get_next_as_val()?)?;
                }
                "preshared-key" => {
                    let peer = current_peer.as_mut().ok_or(no_peer_err)?;
                    let lines = [
                        format!("Change preshared key for {}", peer.public_key),
                        "(or press <Enter> directly to remove the key from the peer).".to_string(),
                        "New key: ".to_string(),
                    ];
                    let prompt = lines.join("\n");
                    peer.preshared_key = Some(read_key(&prompt, &mut reader)?);
                }
                "persistent-keepalive" => {
                    current_peer
                        .as_mut()
                        .ok_or(no_peer_err)?
                        .persistent_keepalive = parse_persistent_keepalive(get_next_as_val()?)?;
                }
                _ => return Err(Error::InvalidArguments(format!("Unknown option `{}`", key))),
            }
        }

        Ok(())
    }

    fn print(&self) {
        // TODO(b/177877310): Print the connection state.
        println!("name: {}", self.name);
        // Always shows local ip since it's mandatory.
        println!(
            "  local ip: {}",
            self.local_ip.as_ref().unwrap_or(&"".to_string())
        );
        println!("  public key: {}", self.public_key);
        println!("  private key: (hidden)");
        if let Some(dns) = &self.name_servers {
            println!("  name servers: {}", dns.join(", "));
        }
        if let Some(mtu) = self.mtu {
            println!("  mtu: {}", mtu);
        }
        println!();
        for p in &self.peers {
            println!("  peer: {}", p.public_key);
            println!("    preshared key: (hidden or not set)");
            println!("    endpoint: {}", p.endpoint);
            println!("    allowed ips: {}", p.allowed_ips);
            println!("    persistent keepalive: {}", p.persistent_keepalive);
            println!();
        }
    }

    // Checks if every required field is filled. We do not check the service state here (i.e., if
    // the service is "Idle", "Connected", or in other states), since shill will return a failure
    // with a proper message immediately if the service is not connectable because of its state.
    fn check_connectability(&self) -> Result<(), Error> {
        for p in &self.peers {
            // `endpoint` is the only required field.
            if p.endpoint.is_empty() {
                return Err(Error::ServiceNotConnectable {
                    service_name: self.name.clone(),
                    reason: format!("Peer {} does not have a valid endpoint", p.public_key),
                });
            }
        }

        Ok(())
    }
}

mod option_util {
    use std::{
        io::{self, Write},
        net::{Ipv4Addr, SocketAddr},
        ops::Range,
    };

    use super::Error;

    // Length of base64-encoded keys for WireGuard (Curve25519).
    pub const WG_BASE64_KEYLEN: usize = 44;

    fn is_valid_i32_in(val: &str, range: Range<i32>) -> bool {
        if let Ok(v) = val.parse::<i32>() {
            range.contains(&v)
        } else {
            false
        }
    }

    fn is_valid_hostname(val: &str) -> bool {
        // Some basic checks for a hostname, as per `man 7 hostname`.
        if !(1..254).contains(&val.len()) {
            return false;
        }
        for c in val.chars() {
            match c {
                'a'..='z' | 'A'..='Z' | '0'..='9' | '-' | '.' => {}
                _ => return false,
            }
        }
        true
    }

    fn is_valid_wg_key(val: &str) -> bool {
        if val.len() != WG_BASE64_KEYLEN {
            return false;
        }
        // The last character must be the padding character given the key length.
        if !val.ends_with('=') {
            return false;
        }
        // Some basic checks for a base64 string.
        for c in val[0..val.len() - 1].chars() {
            match c {
                'a'..='z' | 'A'..='Z' | '0'..='9' | '/' | '+' => {}
                _ => return false,
            }
        }
        true
    }

    // Prompts |prompt| to the user, and reads a base64-encoded WireGuard key from |reader|.
    pub(super) fn read_key<R: io::BufRead>(prompt: &str, reader: &mut R) -> Result<String, Error> {
        let internal_err = |e| Error::Internal(format!("Read error: {}", e));
        print!("{}", prompt);
        io::stdout().flush().map_err(internal_err)?;
        let mut buf = "".to_string();
        reader.read_line(&mut buf).map_err(internal_err)?;
        let buf = buf.trim().to_string();
        if buf.is_empty() || is_valid_wg_key(&buf) {
            Ok(buf)
        } else {
            Err(Error::InvalidArguments(
                "The input is not a valid WireGuard key".to_string(),
            ))
        }
    }

    pub(super) fn parse_local_ip(val: &str) -> Result<String, Error> {
        val.parse::<Ipv4Addr>()
            .map(|ip| ip.to_string())
            .map_err(|_| {
                Error::InvalidArguments(format!(
                    "'local-ip' should contain a valid IPv4 address, but got '{}'",
                    val
                ))
            })
    }

    pub(super) fn parse_dns(val: &str) -> Result<Option<Vec<String>>, Error> {
        if val.is_empty() {
            return Ok(None);
        }

        val.split(',')
            .map(|x| x.parse::<Ipv4Addr>())
            .map(|x| x.map(|y| y.to_string()))
            .collect::<Result<Vec<_>, _>>()
            .map(Some)
            .map_err(|_| {
                Error::InvalidArguments(format!(
                    "'dns' should be a comma-separated list of valid IPv4 addresses, but got '{}'",
                    val
                ))
            })
    }

    pub(super) fn parse_mtu(val: &str) -> Result<Option<i32>, Error> {
        if val.is_empty() {
            return Ok(None);
        }

        match val.parse::<i32>() {
            Ok(0) => Ok(None),
            // [576, 65536) as per wireguard-tools.
            Ok(x) if (576..65536).contains(&x) => Ok(Some(x)),
            _ => Err(Error::InvalidArguments(format!(
                "'mtu' should be in range from 576 to 65535, but got '{}'",
                val
            ))),
        }
    }

    pub(super) fn parse_peer(val: &str) -> Result<String, Error> {
        if is_valid_wg_key(val) {
            Ok(val.to_string())
        } else {
            Err(Error::InvalidArguments(
                "The given value after 'peer' is not a vaild public key".to_string(),
            ))
        }
    }

    pub(super) fn parse_endpoint(val: &str) -> Result<String, Error> {
        if let Ok(s) = val.parse::<SocketAddr>() {
            return Ok(s.to_string());
        }

        let segments: Vec<&str> = val.split(':').collect();
        match segments.as_slice() {
            [h, p] if is_valid_hostname(h) && is_valid_i32_in(p, 1..65536) => Ok(val.to_string()),
            _ => Err(Error::InvalidArguments(format!(
                "'endpoint' should be an IP or hostname, followed by a colon and then a port number, but got '{}'",
                val
            ))),
        }
    }

    pub(super) fn parse_allowed_ips(val: &str) -> Result<String, Error> {
        if val.is_empty() {
            return Ok("".to_string());
        }

        // Currently, only IPv4 addresses are allowed.
        let err = || {
            Error::InvalidArguments(format!("'allowed-ips' should be a common-separated list of IPv4 addresses with CIDR notation, but got '{}'", val))
        };

        // Clears the bits after netmask (e.g., "192.168.1.1/24" => "192.168.1.0/24")
        let formatter = |s: &str| -> Result<String, Error> {
            let segments: Vec<&str> = s.split('/').collect();
            if segments.len() != 2 {
                return Err(err());
            }
            let addr = segments[0].parse::<Ipv4Addr>().map_err(|_| err())?.octets();
            let prefix = segments[1].parse::<i32>().map_err(|_| err())?;
            let addr_u32 = addr.iter().fold(0u32, |acc, x| (acc << 8) + (*x as u32));
            match prefix {
                0..=31 => {
                    let base_addr = Ipv4Addr::from(addr_u32 & !(0xFFFFFFFFu32 >> prefix));
                    Ok(format!("{}/{}", base_addr.to_string(), prefix))
                }
                32 => Ok(s.to_string()),
                _ => Err(err()),
            }
        };

        Ok(val
            .split(',')
            .map(formatter)
            .collect::<Result<Vec<_>, _>>()?
            .join(","))
    }

    pub(super) fn parse_persistent_keepalive(val: &str) -> Result<String, Error> {
        match val {
            "off" => Ok(val.to_string()),
            v if is_valid_i32_in(v, 0..65536) => Ok(val.to_string()),
            _ => Err(Error::InvalidArguments(format!(
                "'persistent-keepalive' should be in range from 0 to 65535, but got '{}'",
                val
            ))),
        }
    }
}

fn make_dbus_connection() -> Result<Connection, Error> {
    Connection::new_system()
        .map_err(|err| Error::Internal(format!("Failed to get D-Bus connection: {}", err)))
}

fn make_manager_proxy(connection: &Connection) -> dbus::blocking::Proxy<&Connection> {
    connection.with_proxy("org.chromium.flimflam", "/", DEFAULT_DBUS_TIMEOUT)
}

fn make_service_proxy<'a>(
    connection: &'a Connection,
    service_path: &'a str,
) -> dbus::blocking::Proxy<'a, &'a Connection> {
    connection.with_proxy("org.chromium.flimflam", service_path, DEFAULT_DBUS_TIMEOUT)
}

// Queries Shill to get all configured WireGuard services.
fn get_wireguard_services(connection: &Connection) -> Result<Vec<WireGuardService>, Error> {
    let manager_proxy = make_manager_proxy(connection);
    let manager_properties: InputPropMap =
        OrgChromiumFlimflamManager::get_properties(&manager_proxy)
            .map_err(|err| Error::Internal(format!("Failed to get Manager properties: {}", err)))?;

    let mut wg_services = Vec::new();

    // The "Services" property should contain a list of D-Bus paths.
    let services = manager_properties.get_strings(PROPERTY_SERVICES)?;
    for path in services {
        let proxy = make_service_proxy(connection, &path);
        let service_properties = OrgChromiumFlimflamService::get_properties(&proxy)
            .map_err(|err| Error::Internal(format!("Failed to get service properties: {}", err)))?;
        match WireGuardService::parse_from_prop_map(&service_properties) {
            Ok(mut service) => {
                service.path = Some(path.to_string());
                wg_services.push(service)
            }
            Err(Error::ServiceNotFound(_)) => continue,
            Err(other_err) => return Err(other_err),
        };
    }

    Ok(wg_services)
}

fn get_wireguard_service_by_name(
    connection: &Connection,
    service_name: &str,
) -> Result<WireGuardService, Error> {
    let services: Vec<WireGuardService> = get_wireguard_services(connection)?
        .into_iter()
        .filter(|x| x.name == service_name)
        .collect();

    match services.len() {
        0 => Err(Error::ServiceNotFound(service_name.to_string())),
        1 => Ok(services.into_iter().next().unwrap()),
        _ => Err(Error::Internal(
            "Found duplicated WireGuard services".to_string(),
        )),
    }
}

fn check_wireguard_support() -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let manager_proxy = make_manager_proxy(&connection);
    let manager_properties: InputPropMap =
        OrgChromiumFlimflamManager::get_properties(&manager_proxy)
            .map_err(|err| Error::Internal(format!("Failed to get Manager properties: {}", err)))?;

    let prohibited_techs = manager_properties.get_string(PROPERTY_PROHIBITED_TECHNOLOGIES)?;
    if prohibited_techs.split(',').any(|x| x == TYPE_VPN) {
        return Err(Error::VpnDisabled);
    }

    let supported_vpns = manager_properties.get_string(PROPERTY_SUPPORTED_VPN_TYPES)?;
    if !supported_vpns.split(',').any(|x| x == TYPE_WIREGUARD) {
        return Err(Error::WireGuardUnavailable);
    }

    Ok(())
}

fn wireguard_list() -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let mut services = get_wireguard_services(&connection)?;
    services.sort_by(|a, b| a.name.cmp(&b.name));
    for service in &services {
        service.print()
    }
    Ok(())
}

fn wireguard_show(service_name: &str) -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    get_wireguard_service_by_name(&connection, service_name)?.print();
    Ok(())
}

fn wireguard_new(service_name: &str) -> Result<(), Error> {
    let connection = make_dbus_connection()?;

    // Checks if there is already a service with the given name.
    match get_wireguard_service_by_name(&connection, service_name) {
        Ok(_) => return Err(Error::ServiceAlreadyExists(service_name.to_string())),
        Err(Error::ServiceNotFound(_)) => {}
        Err(err) => return Err(err),
    };

    let manager_proxy = make_manager_proxy(&connection);
    let service = WireGuardService {
        path: None,
        name: service_name.to_string(),
        local_ip: None,
        private_key: None,
        public_key: "".to_string(),
        name_servers: None,
        mtu: None,
        peers: Vec::new(),
    };
    manager_proxy
        .configure_service(service.encode_into_prop_map())
        .map_err(|err| Error::Internal(format!("Failed to configure service: {}", err)))?;

    println!("Service {} created", service_name);
    Ok(())
}

fn wireguard_set(service_name: &str, args: &[&str]) -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let mut wg_service = get_wireguard_service_by_name(&connection, service_name)?;
    wg_service.update_from_args(args, io::stdin().lock())?;
    let manager_proxy = make_manager_proxy(&connection);
    let properties = wg_service.encode_into_prop_map();
    manager_proxy.configure_service(properties).map_err(|err| {
        error!("ERROR: Failed to configure service: {}", err);
        Error::Internal("".to_string())
    })?;

    println!("Service {} updated", service_name);
    Ok(())
}

fn wireguard_connect(service_name: &str) -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let service = get_wireguard_service_by_name(&connection, service_name)?;
    service.check_connectability()?;
    make_service_proxy(&connection, &service.path.unwrap())
        .connect()
        .map_err(|err| Error::Internal(format!("Failed to connect service: {}", err)))?;

    println!("Connecting to {}..", service_name);
    Ok(())
}

fn wireguard_disconnect(service_name: &str) -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let service = get_wireguard_service_by_name(&connection, service_name)?;
    make_service_proxy(&connection, &service.path.unwrap())
        .disconnect()
        .map_err(|err| Error::Internal(format!("Failed to disconnect service: {}", err)))?;

    println!("Disconnecting from {}..", service_name);
    Ok(())
}

fn wireguard_del(service_name: &str) -> Result<(), Error> {
    let connection = make_dbus_connection()?;
    let service = get_wireguard_service_by_name(&connection, service_name)?;
    make_service_proxy(&connection, &service.path.unwrap())
        .remove()
        .map_err(|err| Error::Internal(format!("Failed to delete service: {}", err)))?;

    println!("Service {} was deleted", service_name);
    Ok(())
}

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

    // Keys are generate randomly by `wireguard-tools`, only for test usages.
    const GOOD_KEYS: [&str; 7] = [
        "",
        "  ",
        "   \n",
        "yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2k=",
        "yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2k=  ",
        "  yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2k=",
        "  yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2k=\n",
    ];
    const BAD_KEYS: [&str; 4] = [
        "abc",
        "abc\n",
        "yJtfKXN4bvw/Dlgp4uRUrbB\nJZDQGojDL7J5mbdh+x2k=",
        "yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2\n",
    ];

    struct TestVars {
        public_key_a: String,
        public_key_b: String,
        public_key_new: String,
        peer_a: WireGuardPeer,
        peer_b: WireGuardPeer,
        service: WireGuardService,
    }

    impl TestVars {
        fn new() -> Self {
            // Keys are generated randomly by `wireguard-tools`, only for test usages.
            let public_key_a: String = "JNy+A9BmLM3wAY/8JrL8KZ0pxIuwZ61FjsrK4DyNXgk=".to_string();
            let public_key_b: String = "IYo3i7xxgCKXEc6Nvawlmg2wO0Qf5ojqvLjz386RmB4=".to_string();
            let public_key_new: String = "LCDxqGY8J5+gXFGh1IqAsMC2CHF6w+oAuegB0nA8Ti4=".to_string();
            let peer_a = WireGuardPeer {
                public_key: public_key_a.clone(),
                endpoint: "10.0.8.1:13579".to_string(),
                allowed_ips: "0.0.0.0/0".to_string(),
                persistent_keepalive: "".to_string(),
                preshared_key: None,
            };
            let peer_b = WireGuardPeer {
                public_key: public_key_b.clone(),
                endpoint: "10.0.10.1:24680".to_string(),
                allowed_ips: "10.8.0.0/16,192.168.100.0/24".to_string(),
                persistent_keepalive: "3".to_string(),
                preshared_key: None,
            };
            let service = WireGuardService {
                path: None,
                name: "wg_test".to_string(),
                local_ip: Some("192.168.1.2".to_string()),
                private_key: None,
                public_key: "".to_string(),
                name_servers: Some(vec!["4.3.2.1".to_string()]),
                mtu: Some(1234),
                peers: vec![peer_a.clone(), peer_b.clone()],
            };
            TestVars {
                public_key_a,
                public_key_b,
                public_key_new,
                peer_a,
                peer_b,
                service,
            }
        }
    }

    #[test]
    fn test_update_local_ip() {
        let vars = TestVars::new();
        let cases = ["192.168.1.1", "10.8.0.3"];
        for c in cases.iter() {
            let mut expected = vars.service.clone();
            expected.local_ip = Some(c.to_string());
            let mut actual = vars.service.clone();
            let args = ["local-ip", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_local_ip_invalid() {
        let vars = TestVars::new();
        let cases = ["", "192.168.1", "abcdabcd", "fe80::1", "1.2.3.4,1.2.3.5"];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["local-ip", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_private_key() {
        let vars = TestVars::new();
        for c in GOOD_KEYS.iter() {
            let mut expected = vars.service.clone();
            expected.private_key = Some(c.trim().to_string());
            let mut actual = vars.service.clone();
            let args = ["private-key"];
            actual.update_from_args(&args, c.as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_private_key_invalid() {
        let vars = TestVars::new();
        for c in BAD_KEYS.iter() {
            let mut actual = vars.service.clone();
            let args = ["private-key"];
            actual.update_from_args(&args, c.as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_dns() {
        let vars = TestVars::new();
        let cases = ["8.8.8.8,1.2.3.4", "8.8.8.8"];
        for c in cases.iter() {
            let mut expected = vars.service.clone();
            expected.name_servers = Some(c.split(',').map(|x| x.to_string()).collect());
            let mut actual = vars.service.clone();
            actual.update_from_args(&["dns", c], "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_dns_default() {
        let vars = TestVars::new();
        let mut expected = vars.service.clone();
        expected.name_servers = None;
        let mut actual = vars.service;
        actual
            .update_from_args(&["dns", ""], "".as_bytes())
            .unwrap();
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_update_dns_invalid() {
        let vars = TestVars::new();
        let cases = ["192.168.1", "abcdabcd", "fe80::1", "8.8.8.8,abc"];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["dns", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_mtu() {
        let vars = TestVars::new();
        let cases = ["576", "1000", "65535"];
        for c in cases.iter() {
            let mut expected = vars.service.clone();
            expected.mtu = Some(c.parse::<i32>().unwrap());
            let mut actual = vars.service.clone();
            actual.update_from_args(&["mtu", c], "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_mtu_default() {
        let vars = TestVars::new();
        let cases = ["0", ""];
        for c in cases.iter() {
            let mut expected = vars.service.clone();
            expected.mtu = None;
            let mut actual = vars.service.clone();
            actual.update_from_args(&["mtu", c], "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_mtu_invalid() {
        let vars = TestVars::new();
        let cases = ["-1", "575", "1000.0", "65536", "abcde"];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["mtu", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_peer_endpoint() {
        let vars = TestVars::new();
        let cases = [
            "192.168.1.1:1234",
            "10.8.0.3:21",
            "[fe80::1]:12345",
            "www.example.com:65535",
            "a-z.A-Z01234.xyz:1111",
        ];

        for c in cases.iter() {
            let mut expected = vars.service.clone();
            let mut updated_peer_b = vars.peer_b.clone();
            updated_peer_b.endpoint = c.to_string();
            expected.peers = vec![vars.peer_a.clone(), updated_peer_b];
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "endpoint", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_peer_endpoint_invalid() {
        let vars = TestVars::new();
        let cases = [
            "fe80::1:12345",  // invalid IPv6 addr with port
            "192.168.1.1:-1", // bad port
            "10.8.0.3:65536",
            "&example.com:1234", // bad hostname
            "example,com:1234",
            ":1234",
        ];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "endpoint", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_peer_allowed_ips() {
        let vars = TestVars::new();

        // Inputs and expected outputs.
        let cases = [
            ("", ""),
            ("0.0.0.0/0", "0.0.0.0/0"),
            ("192.168.12.13/0", "0.0.0.0/0"),
            ("192.168.0.1/32", "192.168.0.1/32"),
            ("192.168.1.0/24", "192.168.1.0/24"),
            ("192.168.1.1/24", "192.168.1.0/24"),
            ("192.168.0.0/16", "192.168.0.0/16"),
            ("192.168.12.13/16", "192.168.0.0/16"),
            ("192.168.128.0/20,10.0.0.0/8", "192.168.128.0/20,10.0.0.0/8"),
        ];

        for c in cases.iter() {
            let mut expected = vars.service.clone();
            let mut updated_peer_b = vars.peer_b.clone();
            updated_peer_b.allowed_ips = c.1.to_string();
            expected.peers = vec![vars.peer_a.clone(), updated_peer_b];
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "allowed-ips", c.0];
            actual.update_from_args(&args, "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_peer_allowed_ips_invalid() {
        let vars = TestVars::new();
        let cases = [
            "fe80::0/32",     // IPv6 is not supported
            "192.168.1.0/-1", // bad CIDR
            "192.168.1.0/256",
            "192.168.128.0/20, 10.0.0.0/8", // additional space
            "192.168.128.0/20;10.0.0.0/8",  // bad separator
        ];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "allowed-ips", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_peer_persistent_keepalive() {
        let vars = TestVars::new();
        let cases = ["off", "0", "1", "300", "65535"];

        for c in cases.iter() {
            let mut expected = vars.service.clone();
            let mut updated_peer_b = vars.peer_b.clone();
            updated_peer_b.persistent_keepalive = c.to_string();
            expected.peers = vec![vars.peer_a.clone(), updated_peer_b];
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "persistent-keepalive", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_peer_persistent_keepalive_invalid() {
        let vars = TestVars::new();
        let cases = ["-1", "1.0", "65536", "abcd", "192.168.1.1", "remove"];
        for c in cases.iter() {
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "persistent-keepalive", c];
            actual.update_from_args(&args, "".as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_peer_preshared_key() {
        let vars = TestVars::new();
        for c in GOOD_KEYS.iter() {
            let mut expected = vars.service.clone();
            let mut updated_peer_b = vars.peer_b.clone();
            updated_peer_b.preshared_key = Some(c.trim().to_string());
            expected.peers = vec![vars.peer_a.clone(), updated_peer_b];
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "preshared-key"];
            actual.update_from_args(&args, c.as_bytes()).unwrap();
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn test_update_peer_preshared_key_invalid() {
        let vars = TestVars::new();
        for c in BAD_KEYS.iter() {
            let mut actual = vars.service.clone();
            let args = ["peer", &vars.public_key_b, "preshared-key"];
            actual.update_from_args(&args, c.as_bytes()).unwrap_err();
        }
    }

    #[test]
    fn test_update_add_peer() {
        let vars = TestVars::new();
        let endpoint_new = "34.56.78.90:45678";

        let mut expected = vars.service.clone();
        expected.peers.push(WireGuardPeer {
            public_key: vars.public_key_new.clone(),
            endpoint: endpoint_new.to_string(),
            allowed_ips: "".to_string(),
            persistent_keepalive: "".to_string(),
            preshared_key: None,
        });

        let mut actual = vars.service.clone();
        let args = ["peer", &vars.public_key_new, "endpoint", endpoint_new];
        actual.update_from_args(&args, "".as_bytes()).unwrap();
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_update_remove_peer() {
        let vars = TestVars::new();
        let mut expected = vars.service.clone();
        expected.peers = vec![vars.peer_b.clone()];
        let mut actual = vars.service.clone();
        let args = ["peer", &vars.public_key_a, "remove"];
        actual.update_from_args(&args, "".as_bytes()).unwrap();
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_update_remove_new_peer() {
        let vars = TestVars::new();
        let mut actual = vars.service.clone();
        let args = ["peer", &vars.public_key_new, "remove"];
        actual.update_from_args(&args, "".as_bytes()).unwrap_err();
    }

    #[test]
    fn test_update_all_in_one() {
        // Keys below generated randomly by `wireguard-tools`, only for test usages.
        let vars = TestVars::new();
        let local_ip = "192.168.99.2";
        let private_key = "yJtfKXN4bvw/Dlgp4uRUrbBJZDQGojDL7J5mbdh+x2k=";
        let endpoint_a = "34.56.78.90:45678";
        let allowed_ips_a = "192.168.101.0/24";
        let persistent_keepalive_a = "21";
        let preshared_key_a = "";
        let endpoint_new = "90.56.78.34:12345";
        let allowed_ips_new = "192.168.102.0/24";
        let persistent_keepalive_new = "off";
        let preshared_key_new = "xZkhH/yBfi3NtT1MzX0iszT03dr1g/0URWEgG5hwCrQ=";
        let updated_peer_a = WireGuardPeer {
            public_key: vars.public_key_a.clone(),
            endpoint: endpoint_a.to_string(),
            allowed_ips: allowed_ips_a.to_string(),
            persistent_keepalive: persistent_keepalive_a.to_string(),
            preshared_key: Some(preshared_key_a.to_string()),
        };
        let new_peer = WireGuardPeer {
            public_key: vars.public_key_new.clone(),
            endpoint: endpoint_new.to_string(),
            allowed_ips: allowed_ips_new.to_string(),
            persistent_keepalive: persistent_keepalive_new.to_string(),
            preshared_key: Some(preshared_key_new.to_string()),
        };

        let mut expected = vars.service.clone();
        expected.local_ip = Some(local_ip.to_string());
        expected.private_key = Some(private_key.to_string());
        expected.name_servers = Some(vec!["8.8.8.8".to_string(), "1.2.3.4".to_string()]);
        expected.mtu = Some(1000);
        expected.peers = vec![updated_peer_a, new_peer];

        let mut cmd = vec!["local-ip", local_ip];
        cmd.extend_from_slice(&["private-key"]);
        cmd.extend_from_slice(&["dns", "8.8.8.8,1.2.3.4", "mtu", "1000"]);
        cmd.extend_from_slice(&["peer", &vars.public_key_b, "remove"]);
        cmd.extend_from_slice(&["peer", &vars.public_key_a, "endpoint", endpoint_a]);
        cmd.extend_from_slice(&["preshared-key"]);
        cmd.extend_from_slice(&["allowed-ips", allowed_ips_a]);
        cmd.extend_from_slice(&["persistent-keepalive", persistent_keepalive_a]);
        cmd.extend_from_slice(&["peer", &vars.public_key_new, "endpoint", endpoint_new]);
        cmd.extend_from_slice(&["allowed-ips", allowed_ips_new]);
        cmd.extend_from_slice(&["persistent-keepalive", persistent_keepalive_new]);
        cmd.extend_from_slice(&["preshared-key"]);

        let input = format!(
            "{}\n{}\n{}\n",
            private_key, preshared_key_a, preshared_key_new
        );

        let mut actual = vars.service;
        actual.update_from_args(&cmd, input.as_bytes()).unwrap();
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_check_connectability() {
        let mut vars = TestVars::new();
        let service = &mut vars.service;
        service.check_connectability().unwrap();
        service.peers[0].endpoint = "".to_string();
        service.check_connectability().unwrap_err();
    }
}
